summaryrefslogtreecommitdiffstats
path: root/generic
diff options
context:
space:
mode:
authorjan.nijtmans <nijtmans@users.sourceforge.net>2023-02-27 11:59:54 (GMT)
committerjan.nijtmans <nijtmans@users.sourceforge.net>2023-02-27 11:59:54 (GMT)
commitc6bb33407aff3661e2f838f4624968de04e3a8e7 (patch)
treeeda6fe8871fb93de04a8b65fff918d8a8d0db48d /generic
parent6ab1efe8062e3be32492d63ed48bd72ed4c62647 (diff)
parented360ca42f9908e5d8da5e8f4742b07d0b148b17 (diff)
downloadtcl-c6bb33407aff3661e2f838f4624968de04e3a8e7.zip
tcl-c6bb33407aff3661e2f838f4624968de04e3a8e7.tar.gz
tcl-c6bb33407aff3661e2f838f4624968de04e3a8e7.tar.bz2
Fix [3d01d51bc4]: Tcl 9: Cannot write large strings to file. Also some size_t -> Tcl_Size changes.
Diffstat (limited to 'generic')
-rw-r--r--generic/tclIO.c116
-rw-r--r--generic/tclIOCmd.c6
2 files changed, 69 insertions, 53 deletions
diff --git a/generic/tclIO.c b/generic/tclIO.c
index 26d0011..768a5c5 100644
--- a/generic/tclIO.c
+++ b/generic/tclIO.c
@@ -102,7 +102,7 @@ typedef struct CopyState {
Tcl_WideInt total; /* Total bytes transferred (written). */
Tcl_Interp *interp; /* Interp that started the copy. */
Tcl_Obj *cmdPtr; /* Command to be invoked at completion. */
- size_t bufSize; /* Size of appended buffer. */
+ Tcl_Size bufSize; /* Size of appended buffer. */
char buffer[TCLFLEXARRAY]; /* Copy buffer, this must be the last
* field. */
} CopyState;
@@ -151,7 +151,7 @@ typedef struct CloseCallback {
* Static functions in this file:
*/
-static ChannelBuffer * AllocChannelBuffer(size_t length);
+static ChannelBuffer * AllocChannelBuffer(Tcl_Size length);
static void PreserveChannelBuffer(ChannelBuffer *bufPtr);
static void ReleaseChannelBuffer(ChannelBuffer *bufPtr);
static int IsShared(ChannelBuffer *bufPtr);
@@ -191,9 +191,9 @@ static int DetachChannel(Tcl_Interp *interp, Tcl_Channel chan);
static void DiscardInputQueued(ChannelState *statePtr,
int discardSavedBuffers);
static void DiscardOutputQueued(ChannelState *chanPtr);
-static int DoRead(Channel *chanPtr, char *dst, size_t bytesToRead,
+static int DoRead(Channel *chanPtr, char *dst, Tcl_Size bytesToRead,
int allowShortReads);
-static int DoReadChars(Channel *chan, Tcl_Obj *objPtr, size_t toRead,
+static int DoReadChars(Channel *chan, Tcl_Obj *objPtr, Tcl_Size toRead,
int appendFlag);
static int FilterInputBytes(Channel *chanPtr,
GetsState *statePtr);
@@ -237,7 +237,7 @@ static int WillRead(Channel *chanPtr);
* short description of what the macro does.
*
* --------------------------------------------------------------------------
- * size_t BytesLeft(ChannelBuffer *bufPtr)
+ * Tcl_Size BytesLeft(ChannelBuffer *bufPtr)
*
* Returns the number of bytes of data remaining in the buffer.
*
@@ -2498,10 +2498,10 @@ Tcl_RemoveChannelMode(
static ChannelBuffer *
AllocChannelBuffer(
- size_t length) /* Desired length of channel buffer. */
+ Tcl_Size length) /* Desired length of channel buffer. */
{
ChannelBuffer *bufPtr;
- size_t n;
+ Tcl_Size n;
n = length + CHANNELBUFFER_HEADER_SIZE + BUFFER_PADDING + BUFFER_PADDING;
bufPtr = (ChannelBuffer *)Tcl_Alloc(n);
@@ -4033,11 +4033,11 @@ Tcl_ClearChannelHandlers(
*----------------------------------------------------------------------
*/
-size_t
+Tcl_Size
Tcl_Write(
Tcl_Channel chan, /* The channel to buffer output for. */
const char *src, /* Data to queue in output buffer. */
- size_t srcLen) /* Length of data in bytes, or -1 for
+ Tcl_Size srcLen) /* Length of data in bytes, or TCL_INDEX_NONE for
* strlen(). */
{
/*
@@ -4087,18 +4087,18 @@ Tcl_Write(
*----------------------------------------------------------------------
*/
-size_t
+Tcl_Size
Tcl_WriteRaw(
Tcl_Channel chan, /* The channel to buffer output for. */
const char *src, /* Data to queue in output buffer. */
- size_t srcLen) /* Length of data in bytes, or -1 for
+ Tcl_Size srcLen) /* Length of data in bytes, or TCL_INDEX_NONE for
* strlen(). */
{
Channel *chanPtr = ((Channel *) chan);
ChannelState *statePtr = chanPtr->state;
/* State info for channel */
int errorCode;
- size_t written;
+ Tcl_Size written;
if (CheckChannelErrors(statePtr, TCL_WRITABLE | CHANNEL_RAW_MODE) != 0) {
return TCL_INDEX_NONE;
@@ -4144,17 +4144,17 @@ Tcl_WriteRaw(
*----------------------------------------------------------------------
*/
-size_t
+Tcl_Size
Tcl_WriteChars(
Tcl_Channel chan, /* The channel to buffer output for. */
const char *src, /* UTF-8 characters to queue in output
* buffer. */
- size_t len) /* Length of string in bytes, or TCL_INDEX_NONE for
+ Tcl_Size len) /* Length of string in bytes, or TCL_INDEX_NONE for
* strlen(). */
{
Channel *chanPtr = (Channel *) chan;
ChannelState *statePtr = chanPtr->state; /* State info for channel */
- size_t result;
+ Tcl_Size result;
Tcl_Obj *objPtr;
if (CheckChannelErrors(statePtr, TCL_WRITABLE) != 0) {
@@ -4219,7 +4219,7 @@ Tcl_WriteChars(
*----------------------------------------------------------------------
*/
-size_t
+Tcl_Size
Tcl_WriteObj(
Tcl_Channel chan, /* The channel to buffer output for. */
Tcl_Obj *objPtr) /* The object to write. */
@@ -4231,7 +4231,6 @@ Tcl_WriteObj(
Channel *chanPtr;
ChannelState *statePtr; /* State info for channel */
const char *src;
- size_t srcLen = 0;
statePtr = ((Channel *) chan)->state;
chanPtr = statePtr->topChanPtr;
@@ -4239,21 +4238,38 @@ Tcl_WriteObj(
if (CheckChannelErrors(statePtr, TCL_WRITABLE) != 0) {
return TCL_INDEX_NONE;
}
- if (statePtr->encoding == NULL) {
- size_t result;
+ Tcl_Size srcLen;
+ if (statePtr->encoding == NULL) {
src = (char *) Tcl_GetByteArrayFromObj(objPtr, &srcLen);
if (src == NULL) {
Tcl_SetErrno(EILSEQ);
- result = TCL_INDEX_NONE;
- } else {
- result = WriteBytes(chanPtr, src, srcLen);
+ return TCL_INDEX_NONE;
}
- return result;
} else {
src = Tcl_GetStringFromObj(objPtr, &srcLen);
- return WriteChars(chanPtr, src, srcLen);
}
+
+ size_t totalWritten = 0;
+ /*
+ * Note original code always called WriteChars even if srcLen 0
+ * so we will too.
+ */
+ do {
+ int chunkSize = srcLen > INT_MAX ? INT_MAX : srcLen;
+ int written;
+ if (statePtr->encoding == NULL) {
+ written = WriteBytes(chanPtr, src, chunkSize);
+ } else {
+ written = WriteChars(chanPtr, src, chunkSize);
+ }
+ if (written < 0) {
+ return TCL_INDEX_NONE;
+ }
+ totalWritten += written;
+ srcLen -= chunkSize;
+ } while (srcLen);
+ return totalWritten;
}
static void
@@ -4550,7 +4566,7 @@ Write(
*---------------------------------------------------------------------------
*/
-size_t
+Tcl_Size
Tcl_Gets(
Tcl_Channel chan, /* Channel from which to read. */
Tcl_DString *lineRead) /* The line read will be appended to this
@@ -4559,7 +4575,7 @@ Tcl_Gets(
* for managing the storage. */
{
Tcl_Obj *objPtr;
- size_t charsStored;
+ Tcl_Size charsStored;
TclNewObj(objPtr);
charsStored = Tcl_GetsObj(chan, objPtr);
@@ -4593,7 +4609,7 @@ Tcl_Gets(
*---------------------------------------------------------------------------
*/
-size_t
+Tcl_Size
Tcl_GetsObj(
Tcl_Channel chan, /* Channel from which to read. */
Tcl_Obj *objPtr) /* The line read will be appended to this
@@ -4605,7 +4621,7 @@ Tcl_GetsObj(
/* State info for channel */
ChannelBuffer *bufPtr;
int inEofChar, skip, copiedTotal, oldFlags, oldRemoved;
- size_t oldLength;
+ Tcl_Size oldLength;
Tcl_Encoding encoding;
char *dst, *dstEnd, *eol, *eof;
Tcl_EncodingState oldState;
@@ -4775,7 +4791,7 @@ Tcl_GetsObj(
*/
if (eol >= dstEnd) {
- size_t offset;
+ Tcl_Size offset;
if (eol != eof) {
offset = eol - objPtr->bytes;
@@ -5045,7 +5061,7 @@ TclGetsObjBinary(
/* State info for channel */
ChannelBuffer *bufPtr;
int inEofChar, skip, copiedTotal, oldFlags, oldRemoved;
- size_t rawLen, byteLen = 0, oldLength;
+ Tcl_Size rawLen, byteLen = 0, oldLength;
int eolChar;
unsigned char *dst, *dstEnd, *eol, *eof, *byteArray;
@@ -5313,7 +5329,7 @@ FreeBinaryEncoding(
}
static Tcl_Encoding
-GetBinaryEncoding()
+GetBinaryEncoding(void)
{
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
@@ -5711,11 +5727,11 @@ CommonGetsCleanup(
*----------------------------------------------------------------------
*/
-size_t
+Tcl_Size
Tcl_Read(
Tcl_Channel chan, /* The channel from which to read. */
char *dst, /* Where to store input read. */
- size_t bytesToRead) /* Maximum number of bytes to read. */
+ Tcl_Size bytesToRead) /* Maximum number of bytes to read. */
{
Channel *chanPtr = (Channel *) chan;
ChannelState *statePtr = chanPtr->state;
@@ -5756,11 +5772,11 @@ Tcl_Read(
*----------------------------------------------------------------------
*/
-size_t
+Tcl_Size
Tcl_ReadRaw(
Tcl_Channel chan, /* The channel from which to read. */
char *readBuf, /* Where to store input read. */
- size_t bytesToRead) /* Maximum number of bytes to read. */
+ Tcl_Size bytesToRead) /* Maximum number of bytes to read. */
{
Channel *chanPtr = (Channel *) chan;
ChannelState *statePtr = chanPtr->state;
@@ -5839,8 +5855,8 @@ Tcl_ReadRaw(
}
} else if (nread > 0) {
/*
- * Successful read (short is OK) - add to bytes copied.
- */
+ * Successful read (short is OK) - add to bytes copied.
+ */
copied += nread;
} else {
@@ -5874,11 +5890,11 @@ Tcl_ReadRaw(
*---------------------------------------------------------------------------
*/
-size_t
+Tcl_Size
Tcl_ReadChars(
Tcl_Channel chan, /* The channel to read. */
Tcl_Obj *objPtr, /* Input data is stored in this object. */
- size_t toRead, /* Maximum number of characters to store, or
+ Tcl_Size toRead, /* Maximum number of characters to store, or
* TCL_INDEX_NONE to read all available data (up to EOF or
* when channel blocks). */
int appendFlag) /* If non-zero, data read from the channel
@@ -5934,7 +5950,7 @@ static int
DoReadChars(
Channel *chanPtr, /* The channel to read. */
Tcl_Obj *objPtr, /* Input data is stored in this object. */
- size_t toRead, /* Maximum number of characters to store, or
+ Tcl_Size toRead, /* Maximum number of characters to store, or
* TCL_INDEX_NONE to read all available data (up to EOF or
* when channel blocks). */
int appendFlag) /* If non-zero, data read from the channel
@@ -6226,7 +6242,7 @@ ReadChars(
int savedIEFlags = statePtr->inputEncodingFlags;
int savedFlags = statePtr->flags;
char *dst, *src = RemovePoint(bufPtr);
- size_t numBytes;
+ Tcl_Size numBytes;
int srcLen = BytesLeft(bufPtr);
/*
@@ -6784,11 +6800,11 @@ TranslateInputEOL(
*----------------------------------------------------------------------
*/
-size_t
+Tcl_Size
Tcl_Ungets(
Tcl_Channel chan, /* The channel for which to add the input. */
const char *str, /* The input itself. */
- size_t len, /* The length of the input. */
+ Tcl_Size len, /* The length of the input. */
int atEnd) /* If non-zero, add at end of queue; otherwise
* add at head of queue. */
{
@@ -7706,7 +7722,7 @@ Tcl_ChannelBuffered(
void
Tcl_SetChannelBufferSize(
Tcl_Channel chan, /* The channel whose buffer size to set. */
- size_t sz) /* The size to set. */
+ Tcl_Size sz) /* The size to set. */
{
ChannelState *statePtr; /* State of real channel structure. */
@@ -7760,7 +7776,7 @@ Tcl_SetChannelBufferSize(
*----------------------------------------------------------------------
*/
-size_t
+Tcl_Size
Tcl_GetChannelBufferSize(
Tcl_Channel chan) /* The channel for which to find the buffer
* size. */
@@ -7812,7 +7828,7 @@ Tcl_BadChannelOption(
const char *genericopt =
"blocking buffering buffersize encoding eofchar nocomplainencoding strictencoding translation";
const char **argv;
- size_t argc, i;
+ Tcl_Size argc, i;
Tcl_DString ds;
Tcl_Obj *errObj;
@@ -8094,7 +8110,7 @@ Tcl_SetChannelOption(
ChannelState *statePtr = chanPtr->state;
/* State info for channel */
size_t len; /* Length of optionName string. */
- size_t argc;
+ Tcl_Size argc;
const char **argv = NULL;
/*
@@ -9652,7 +9668,7 @@ CopyData(
Tcl_Channel inChan, outChan;
ChannelState *inStatePtr, *outStatePtr;
int result = TCL_OK, size;
- size_t sizeb;
+ Tcl_Size sizeb;
Tcl_WideInt total;
const char *buffer;
int inBinary, outBinary, sameEncoding;
@@ -9990,7 +10006,7 @@ static int
DoRead(
Channel *chanPtr, /* The channel from which to read. */
char *dst, /* Where to store input read. */
- size_t bytesToRead, /* Maximum number of bytes to read. */
+ Tcl_Size bytesToRead, /* Maximum number of bytes to read. */
int allowShortReads) /* Allow half-blocking (pipes,sockets) */
{
ChannelState *statePtr = chanPtr->state;
@@ -11088,7 +11104,7 @@ FixLevelCode(
Tcl_Obj *msg)
{
int explicitResult, numOptions, lcn;
- size_t lc;
+ Tcl_Size lc;
Tcl_Obj **lv, **lvn;
int res, i, j, val, lignore, cignore;
int newlevel = -1, newcode = -1;
diff --git a/generic/tclIOCmd.c b/generic/tclIOCmd.c
index 4ce27bb..197ca32 100644
--- a/generic/tclIOCmd.c
+++ b/generic/tclIOCmd.c
@@ -106,7 +106,7 @@ Tcl_PutsObjCmd(
Tcl_Obj *string; /* String to write. */
Tcl_Obj *chanObjPtr = NULL; /* channel object. */
int newline; /* Add a newline at end? */
- int result; /* Result of puts operation. */
+ size_t result; /* Result of puts operation. */
int mode; /* Mode in which channel is opened. */
switch (objc) {
@@ -163,12 +163,12 @@ Tcl_PutsObjCmd(
TclChannelPreserve(chan);
result = Tcl_WriteObj(chan, string);
- if (result == -1) {
+ if (result == TCL_INDEX_NONE) {
goto error;
}
if (newline != 0) {
result = Tcl_WriteChars(chan, "\n", 1);
- if (result == -1) {
+ if (result == TCL_INDEX_NONE) {
goto error;
}
}