diff options
author | jan.nijtmans <nijtmans@users.sourceforge.net> | 2022-05-19 11:00:04 (GMT) |
---|---|---|
committer | jan.nijtmans <nijtmans@users.sourceforge.net> | 2022-05-19 11:00:04 (GMT) |
commit | b4b177bc926f1e246054462ba147e0448a0a95e3 (patch) | |
tree | 683daa1e2e627a09aad80ed74f28dc0e54a00218 | |
parent | 2e04ff831d043373741c9252f3ff791bbc2bbda9 (diff) | |
download | tcl-b4b177bc926f1e246054462ba147e0448a0a95e3.zip tcl-b4b177bc926f1e246054462ba147e0448a0a95e3.tar.gz tcl-b4b177bc926f1e246054462ba147e0448a0a95e3.tar.bz2 |
Elaborate TIP #481 implementation: Make clear that Tcl_GetUnicodeFromObj and Tcl_GetStringFromObj panic if lengthPtr points to an int and length > INT_MAX.
Also if sizeof(int) == sizeof(size_t), prefer the size_t variant of the functions
-rw-r--r-- | doc/StringObj.3 | 7 | ||||
-rw-r--r-- | generic/tclDecls.h | 16 | ||||
-rw-r--r-- | generic/tclObj.c | 6 | ||||
-rw-r--r-- | generic/tclStringObj.c | 4 |
4 files changed, 22 insertions, 11 deletions
diff --git a/doc/StringObj.3 b/doc/StringObj.3 index c9bdd4a..2526a01 100644 --- a/doc/StringObj.3 +++ b/doc/StringObj.3 @@ -188,7 +188,9 @@ Even in the limited situations where writing to this pointer is acceptable, one should take care to respect the copy-on-write semantics required by \fBTcl_Obj\fR's, with appropriate calls to \fBTcl_IsShared\fR and \fBTcl_DuplicateObj\fR prior to any -in-place modification of the string representation. +in-place modification of the string representation. If \fIlengthPtr\fR +points to an \fBint\fR variable, and the string has more than 2^31 bytes, +a panic will result. The procedure \fBTcl_GetString\fR is used in the common case where the caller does not need the length of the string representation. @@ -200,7 +202,8 @@ value as a Unicode string. This is given by the returned pointer and byte pointer is owned by the value manager and should not be modified by the caller. The procedure \fBTcl_GetUnicode\fR is used in the common case where the caller does not need the length of the unicode string -representation. +representation. If \fIlengthPtr\fR points to an \fBint\fR variable, +and the string has more than 2^31 unicode characters, a panic will result. .PP \fBTcl_GetUniChar\fR returns the \fIindex\fR'th character in the value's Unicode representation. If the index is out of range or diff --git a/generic/tclDecls.h b/generic/tclDecls.h index 0995678..02c365e 100644 --- a/generic/tclDecls.h +++ b/generic/tclDecls.h @@ -3916,24 +3916,24 @@ extern const TclStubs *tclStubsPtr; #undef Tcl_GetBytesFromObj #if defined(USE_TCL_STUBS) #define Tcl_GetStringFromObj(objPtr, sizePtr) \ - (sizeof(*(sizePtr)) <= sizeof(int) ? tclStubsPtr->tclGetStringFromObj(objPtr, (int *)(sizePtr)) : tclStubsPtr->tcl_GetStringFromObj(objPtr, (size_t *)(sizePtr))) + ((sizeof(*(sizePtr)) <= sizeof(int) && sizeof(int) != sizeof(size_t)) ? tclStubsPtr->tclGetStringFromObj(objPtr, (int *)(sizePtr)) : tclStubsPtr->tcl_GetStringFromObj(objPtr, (size_t *)(sizePtr))) #define Tcl_GetBytesFromObj(interp, objPtr, sizePtr) \ - (sizeof(*(sizePtr)) <= sizeof(int) ? tclStubsPtr->tclGetBytesFromObj(interp, objPtr, (int *)(sizePtr)) : tclStubsPtr->tcl_GetBytesFromObj(interp, objPtr, (size_t *)(sizePtr))) + ((sizeof(*(sizePtr)) <= sizeof(int)) ? tclStubsPtr->tclGetBytesFromObj(interp, objPtr, (int *)(sizePtr)) : tclStubsPtr->tcl_GetBytesFromObj(interp, objPtr, (size_t *)(sizePtr))) #define Tcl_GetByteArrayFromObj(objPtr, sizePtr) \ - (sizeof(*(sizePtr)) <= sizeof(int) ? tclStubsPtr->tclGetBytesFromObj(NULL, objPtr, (int *)(sizePtr)) : tclStubsPtr->tcl_GetBytesFromObj(NULL, objPtr, (size_t *)(sizePtr))) + ((sizeof(*(sizePtr)) <= sizeof(int)) ? tclStubsPtr->tclGetBytesFromObj(NULL, objPtr, (int *)(sizePtr)) : tclStubsPtr->tcl_GetBytesFromObj(NULL, objPtr, (size_t *)(sizePtr))) #define Tcl_GetUnicodeFromObj(objPtr, sizePtr) \ - (sizeof(*(sizePtr)) <= sizeof(int) ? tclStubsPtr->tclGetUnicodeFromObj(objPtr, (int *)(sizePtr)) : tclStubsPtr->tcl_GetUnicodeFromObj(objPtr, (size_t *)(sizePtr))) + ((sizeof(*(sizePtr)) <= sizeof(int)) ? tclStubsPtr->tclGetUnicodeFromObj(objPtr, (int *)(sizePtr)) : tclStubsPtr->tcl_GetUnicodeFromObj(objPtr, (size_t *)(sizePtr))) #define Tcl_GetIndexFromObjStruct(interp, objPtr, tablePtr, offset, msg, flags, indexPtr) \ (tclStubsPtr->tcl_GetIndexFromObjStruct((interp), (objPtr), (tablePtr), (offset), (msg), (flags)|(int)(sizeof(*(indexPtr))<<1), (indexPtr))) #else #define Tcl_GetStringFromObj(objPtr, sizePtr) \ - (sizeof(*(sizePtr)) <= sizeof(int) ? (TclGetStringFromObj)(objPtr, (int *)(sizePtr)) : (Tcl_GetStringFromObj)(objPtr, (size_t *)(sizePtr))) + ((sizeof(*(sizePtr)) <= sizeof(int) && sizeof(int) != sizeof(size_t)) ? (TclGetStringFromObj)(objPtr, (int *)(sizePtr)) : (Tcl_GetStringFromObj)(objPtr, (size_t *)(sizePtr))) #define Tcl_GetBytesFromObj(interp, objPtr, sizePtr) \ - (sizeof(*(sizePtr)) <= sizeof(int) ? (TclGetBytesFromObj)(interp, objPtr, (int *)(sizePtr)) : (Tcl_GetBytesFromObj)(interp, objPtr, (size_t *)(sizePtr))) + ((sizeof(*(sizePtr)) <= sizeof(int) && sizeof(int) != sizeof(size_t)) ? (TclGetBytesFromObj)(interp, objPtr, (int *)(sizePtr)) : (Tcl_GetBytesFromObj)(interp, objPtr, (size_t *)(sizePtr))) #define Tcl_GetByteArrayFromObj(objPtr, sizePtr) \ - (sizeof(*(sizePtr)) <= sizeof(int) ? (TclGetBytesFromObj)(NULL, objPtr, (int *)(sizePtr)) : (Tcl_GetBytesFromObj)(NULL, objPtr, (size_t *)(sizePtr))) + ((sizeof(*(sizePtr)) <= sizeof(int) && sizeof(int) != sizeof(size_t)) ? (TclGetBytesFromObj)(NULL, objPtr, (int *)(sizePtr)) : (Tcl_GetBytesFromObj)(NULL, objPtr, (size_t *)(sizePtr))) #define Tcl_GetUnicodeFromObj(objPtr, sizePtr) \ - (sizeof(*(sizePtr)) <= sizeof(int) ? (TclGetUnicodeFromObj)(objPtr, (int *)(sizePtr)) : Tcl_GetUnicodeFromObj(objPtr, (size_t *)(sizePtr))) + ((sizeof(*(sizePtr)) <= sizeof(int) && sizeof(int) != sizeof(size_t)) ? (TclGetUnicodeFromObj)(objPtr, (int *)(sizePtr)) : Tcl_GetUnicodeFromObj(objPtr, (size_t *)(sizePtr))) #define Tcl_GetIndexFromObjStruct(interp, objPtr, tablePtr, offset, msg, flags, indexPtr) \ ((Tcl_GetIndexFromObjStruct)((interp), (objPtr), (tablePtr), (offset), (msg), (flags)|(int)(sizeof(*(indexPtr))<<1), (indexPtr))) #endif diff --git a/generic/tclObj.c b/generic/tclObj.c index b4d6332..300e408 100644 --- a/generic/tclObj.c +++ b/generic/tclObj.c @@ -1675,7 +1675,11 @@ TclGetStringFromObj( } } if (lengthPtr != NULL) { - *lengthPtr = (objPtr->length < INT_MAX)? objPtr->length: INT_MAX; + if (objPtr->length > INT_MAX) { + Tcl_Panic("Tcl_GetStringFromObj with 'int' lengthPtr" + "cannot handle such long strings. Please use 'size_t'"); + } + *lengthPtr = (int)objPtr->length; } return objPtr->bytes; } diff --git a/generic/tclStringObj.c b/generic/tclStringObj.c index a3ee1c3..d0bac17 100644 --- a/generic/tclStringObj.c +++ b/generic/tclStringObj.c @@ -686,6 +686,10 @@ TclGetUnicodeFromObj( } if (lengthPtr != NULL) { + if (stringPtr->numChars > INT_MAX) { + Tcl_Panic("Tcl_GetUnicodeFromObj with 'int' lengthPtr" + "cannot handle such long strings. Please use 'size_t'"); + } *lengthPtr = (int)stringPtr->numChars; } return stringPtr->unicode; |