From ddf4a5f1583b7a5c030020dcf4a1e712b5d465f2 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Thu, 24 Nov 2022 14:05:58 +0000 Subject: Use Tcl_GetByteArrayFromObj(... in stead of Tcl_GetBytesFromObj(NULL,.... Add some more error-checking for invalid byte-arrays --- generic/tclBinary.c | 14 +++++++------- generic/tclConfig.c | 5 ++++- generic/tclExecute.c | 4 ++-- generic/tclIO.c | 8 ++++++-- generic/tclIORChan.c | 2 +- generic/tclLink.c | 4 +++- generic/tclStringObj.c | 6 +++--- generic/tclZipfs.c | 2 +- generic/tclZlib.c | 10 ++++++++-- 9 files changed, 35 insertions(+), 20 deletions(-) diff --git a/generic/tclBinary.c b/generic/tclBinary.c index 07c78a8..28cf31d 100644 --- a/generic/tclBinary.c +++ b/generic/tclBinary.c @@ -912,9 +912,9 @@ BinaryFormatCmd( goto badIndex; } if (count == BINARY_ALL) { - Tcl_Obj *copy = TclNarrowToBytes(objv[arg]); - (void)Tcl_GetByteArrayFromObj(copy, &count); - Tcl_DecrRefCount(copy); + if (Tcl_GetByteArrayFromObj(objv[arg], &count) == NULL) { + count = Tcl_GetCharLength(objv[arg]); + } } else if (count == BINARY_NOCOUNT) { count = 1; } @@ -2524,7 +2524,7 @@ BinaryDecodeHex( } TclNewObj(resultObj); - data = Tcl_GetBytesFromObj(NULL, objv[objc - 1], &count); + data = Tcl_GetByteArrayFromObj(objv[objc - 1], &count); if (data == NULL) { pure = 0; data = (unsigned char *) Tcl_GetStringFromObj(objv[objc - 1], &count); @@ -2657,7 +2657,7 @@ BinaryEncode64( } break; case OPT_WRAPCHAR: - wrapchar = (const char *)Tcl_GetBytesFromObj(NULL, + wrapchar = (const char *)Tcl_GetByteArrayFromObj( objv[i + 1], &wrapcharlen); if (wrapchar == NULL) { purewrap = 0; @@ -2928,7 +2928,7 @@ BinaryDecodeUu( } TclNewObj(resultObj); - data = Tcl_GetBytesFromObj(NULL, objv[objc - 1], &count); + data = Tcl_GetByteArrayFromObj(objv[objc - 1], &count); if (data == NULL) { pure = 0; data = (unsigned char *) Tcl_GetStringFromObj(objv[objc - 1], &count); @@ -3103,7 +3103,7 @@ BinaryDecode64( } TclNewObj(resultObj); - data = Tcl_GetBytesFromObj(NULL, objv[objc - 1], &count); + data = Tcl_GetByteArrayFromObj(objv[objc - 1], &count); if (data == NULL) { pure = 0; data = (unsigned char *) Tcl_GetStringFromObj(objv[objc - 1], &count); diff --git a/generic/tclConfig.c b/generic/tclConfig.c index fcd991a..1ece31c 100644 --- a/generic/tclConfig.c +++ b/generic/tclConfig.c @@ -258,7 +258,10 @@ QueryConfigObjCmd( * Value is stored as-is in a byte array, see Bug [9b2e636361], * so we have to decode it first. */ - value = (const char *) Tcl_GetByteArrayFromObj(val, &n); + value = (const char *) Tcl_GetBytesFromObj(interp, val, &n); + if (value == NULL) { + return TCL_ERROR; + } value = Tcl_ExternalToUtfDString(venc, value, n, &conv); Tcl_SetObjResult(interp, Tcl_NewStringObj(value, Tcl_DStringLength(&conv))); diff --git a/generic/tclExecute.c b/generic/tclExecute.c index 926fd61..950cabe 100644 --- a/generic/tclExecute.c +++ b/generic/tclExecute.c @@ -5274,7 +5274,7 @@ TEBCresume( TclNewObj(objResultPtr); } else if (TclIsPureByteArray(valuePtr)) { objResultPtr = Tcl_NewByteArrayObj( - Tcl_GetBytesFromObj(NULL, valuePtr, (size_t *)NULL)+index, 1); + Tcl_GetByteArrayFromObj(valuePtr, (size_t *)NULL)+index, 1); } else if (valuePtr->bytes && slength == valuePtr->length) { objResultPtr = Tcl_NewStringObj((const char *) valuePtr->bytes+index, 1); @@ -5536,7 +5536,7 @@ TEBCresume( ustring2 = Tcl_GetUnicodeFromObj(value2Ptr, &length2); match = TclUniCharMatch(ustring1, slength, ustring2, length2, nocase); - } else if (TclIsPureByteArray(valuePtr) && !nocase) { + } else if (TclIsPureByteArray(valuePtr) && TclIsPureByteArray(value2Ptr) && !nocase) { unsigned char *bytes1, *bytes2; size_t wlen1 = 0, wlen2 = 0; diff --git a/generic/tclIO.c b/generic/tclIO.c index 26db2f4..1541390 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -4638,7 +4638,7 @@ Tcl_GetsObj( if ((statePtr->encoding == NULL) && ((statePtr->inputTranslation == TCL_TRANSLATE_LF) || (statePtr->inputTranslation == TCL_TRANSLATE_CR)) - && Tcl_GetBytesFromObj(NULL, objPtr, (size_t *)NULL) != NULL) { + && Tcl_GetByteArrayFromObj(objPtr, (size_t *)NULL) != NULL) { return TclGetsObjBinary(chan, objPtr); } @@ -5057,6 +5057,10 @@ TclGetsObjBinary( */ byteArray = Tcl_GetByteArrayFromObj(objPtr, &byteLen); + if (byteArray == NULL) { + Tcl_SetErrno(EILSEQ); + return -1; + } oldFlags = statePtr->inputEncodingFlags; oldRemoved = BUFFER_PADDING; oldLength = byteLen; @@ -5945,7 +5949,7 @@ DoReadChars( && (statePtr->inEofChar == '\0'); if (appendFlag) { - if (binaryMode && (NULL == Tcl_GetBytesFromObj(NULL, objPtr, (size_t *)NULL))) { + if (binaryMode && (NULL == Tcl_GetByteArrayFromObj(objPtr, (size_t *)NULL))) { binaryMode = 0; } } else { diff --git a/generic/tclIORChan.c b/generic/tclIORChan.c index 67abca6..5bf7ea4 100644 --- a/generic/tclIORChan.c +++ b/generic/tclIORChan.c @@ -1387,7 +1387,7 @@ ReflectInput( if (bytev == NULL) { SetChannelErrorStr(rcPtr->chan, msg_read_nonbyte); - goto invalid; + goto invalid; } else if ((size_t)toRead < bytec) { SetChannelErrorStr(rcPtr->chan, msg_read_toomuch); goto invalid; diff --git a/generic/tclLink.c b/generic/tclLink.c index a0212ee..0088950 100644 --- a/generic/tclLink.c +++ b/generic/tclLink.c @@ -880,7 +880,9 @@ LinkTraceProc( case TCL_LINK_BINARY: value = (char *) Tcl_GetByteArrayFromObj(valueObj, &valueLength); - if (valueLength != linkPtr->bytes) { + if (value == NULL) { + return (char *) "invalid binary value"; + } else if (valueLength != linkPtr->bytes) { return (char *) "wrong size of binary value"; } if (linkPtr->flags & LINK_ALLOC_LAST) { diff --git a/generic/tclStringObj.c b/generic/tclStringObj.c index 743f0ed..545a1e0 100644 --- a/generic/tclStringObj.c +++ b/generic/tclStringObj.c @@ -1471,7 +1471,7 @@ Tcl_AppendObjToObj( */ TclAppendBytesToByteArray(objPtr, - Tcl_GetBytesFromObj(NULL, appendObjPtr, (size_t *)NULL), lengthSrc); + Tcl_GetByteArrayFromObj(appendObjPtr, (size_t *)NULL), lengthSrc); return; } @@ -3000,7 +3000,7 @@ TclStringRepeat( done *= 2; } TclAppendBytesToByteArray(objResultPtr, - Tcl_GetBytesFromObj(NULL, objResultPtr, (size_t *)NULL), + Tcl_GetByteArrayFromObj(objResultPtr, (size_t *)NULL), (count - done) * length); } else if (unichar) { /* @@ -3884,7 +3884,7 @@ TclStringReverse( if (!inPlace || Tcl_IsShared(objPtr)) { objPtr = Tcl_NewByteArrayObj(NULL, numBytes); } - ReverseBytes(Tcl_GetBytesFromObj(NULL, objPtr, (size_t *)NULL), from, numBytes); + ReverseBytes(Tcl_GetByteArrayFromObj(objPtr, (size_t *)NULL), from, numBytes); return objPtr; } diff --git a/generic/tclZipfs.c b/generic/tclZipfs.c index c7bf4f9..45f65fe 100644 --- a/generic/tclZipfs.c +++ b/generic/tclZipfs.c @@ -2409,7 +2409,7 @@ ZipFSMkKeyObjCmd( } passObj = Tcl_NewByteArrayObj(NULL, 264); - passBuf = Tcl_GetBytesFromObj(NULL, passObj, (size_t *)NULL); + passBuf = Tcl_GetByteArrayFromObj(passObj, (size_t *)NULL); while (len > 0) { int ch = pw[len - 1]; diff --git a/generic/tclZlib.c b/generic/tclZlib.c index 1077b7c..5a6dbc4 100644 --- a/generic/tclZlib.c +++ b/generic/tclZlib.c @@ -597,6 +597,9 @@ SetInflateDictionary( size_t length = 0; unsigned char *bytes = Tcl_GetByteArrayFromObj(compDictObj, &length); + if (bytes == NULL) { + return Z_DATA_ERROR; + } return inflateSetDictionary(strm, bytes, length); } return Z_OK; @@ -611,6 +614,9 @@ SetDeflateDictionary( size_t length = 0; unsigned char *bytes = Tcl_GetByteArrayFromObj(compDictObj, &length); + if (bytes == NULL) { + return Z_DATA_ERROR; + } return deflateSetDictionary(strm, bytes, length); } return Z_OK; @@ -1154,7 +1160,7 @@ Tcl_ZlibStreamSetCompressionDictionary( { ZlibStreamHandle *zshPtr = (ZlibStreamHandle *) zshandle; - if (compressionDictionaryObj && (NULL == Tcl_GetBytesFromObj(NULL, + if (compressionDictionaryObj && (NULL == Tcl_GetByteArrayFromObj( compressionDictionaryObj, (size_t *)NULL))) { /* Missing or invalid compression dictionary */ compressionDictionaryObj = NULL; @@ -3722,7 +3728,7 @@ ZlibStackChannelTransform( if (compDictObj != NULL) { cd->compDictObj = Tcl_DuplicateObj(compDictObj); Tcl_IncrRefCount(cd->compDictObj); - Tcl_GetBytesFromObj(NULL, cd->compDictObj, (size_t *)NULL); + Tcl_GetByteArrayFromObj(cd->compDictObj, (size_t *)NULL); } if (format == TCL_ZLIB_FORMAT_RAW) { -- cgit v0.12