diff options
| author | apnadkarni <apnmbx-wits@yahoo.com> | 2023-05-03 13:18:05 (GMT) |
|---|---|---|
| committer | apnadkarni <apnmbx-wits@yahoo.com> | 2023-05-03 13:18:05 (GMT) |
| commit | 688c125ec305e23f82299d3b321a9c262e8af35f (patch) | |
| tree | d9bad154bfc3010cffe6924a9f61fc9499a00ace | |
| parent | 06cc962945bd148c0fb2a63ab23e6e3577945929 (diff) | |
| download | tcl-688c125ec305e23f82299d3b321a9c262e8af35f.zip tcl-688c125ec305e23f82299d3b321a9c262e8af35f.tar.gz tcl-688c125ec305e23f82299d3b321a9c262e8af35f.tar.bz2 | |
Fix bug-c9663296fd (in progress)
| -rw-r--r-- | generic/tclStringObj.c | 56 | ||||
| -rw-r--r-- | generic/tclStringRep.h | 7 |
2 files changed, 38 insertions, 25 deletions
diff --git a/generic/tclStringObj.c b/generic/tclStringObj.c index d2bc1b2..33e61a6 100644 --- a/generic/tclStringObj.c +++ b/generic/tclStringObj.c @@ -131,8 +131,8 @@ const Tcl_ObjType tclStringType = { static void GrowStringBuffer( Tcl_Obj *objPtr, - size_t needed, - int flag) + size_t needed, /* Not including terminating nul */ + int flag) /* If 0, try to overallocate */ { /* * Preconditions: @@ -145,11 +145,18 @@ GrowStringBuffer( char *ptr = NULL; size_t attempt; + assert(needed <= TCL_SIZE_MAX - 1); + if (objPtr->bytes == &tclEmptyString) { objPtr->bytes = NULL; } if (flag == 0 || stringPtr->allocated > 0) { - attempt = 2 * needed; + if (needed <= (TCL_SIZE_MAX - needed - 1)) { + /* Doubling space will not overflow */ + attempt = 2 * needed; + } else { + attempt = TCL_SIZE_MAX - 1; + } ptr = (char *)Tcl_AttemptRealloc(objPtr->bytes, attempt + 1U); if (ptr == NULL) { /* @@ -157,11 +164,11 @@ GrowStringBuffer( * overflow into invalid argument values for attempt. */ - size_t limit = INT_MAX - needed; - size_t extra = needed - objPtr->length + TCL_MIN_GROWTH; - size_t growth = (extra > limit) ? limit : extra; - - attempt = needed + growth; + if (needed < (TCL_SIZE_MAX - TCL_MIN_GROWTH - 1)) { + attempt = needed + TCL_MIN_GROWTH; + } else { + attempt = TCL_SIZE_MAX - 1; + } ptr = (char *)Tcl_AttemptRealloc(objPtr->bytes, attempt + 1U); } } @@ -190,32 +197,37 @@ GrowUnicodeBuffer( String *ptr = NULL, *stringPtr = GET_STRING(objPtr); size_t attempt; + size_t bytesNeeded; /* Actual storage including header */ + /* Note STRING_MAXCHARS already takes into account space for nul */ + if (needed > STRING_MAXCHARS) { + Tcl_Panic("max size for a Tcl unicode rep (%" TCL_Z_MODIFIER "d bytes) exceeded", + STRING_MAXCHARS); + } if (stringPtr->maxChars > 0) { - /* - * Subsequent appends - apply the growth algorithm. - */ - - attempt = 2 * needed; + /* Subsequent appends - apply the growth algorithm. */ + if (needed <= (STRING_MAXCHARS - needed)) { + /* Doubling space will not overflow */ + attempt = 2 * needed; + } else { + attempt = STRING_MAXCHARS; + } ptr = stringAttemptRealloc(stringPtr, attempt); if (ptr == NULL) { /* * Take care computing the amount of modest growth to avoid * overflow into invalid argument values for attempt. */ - - size_t extra = needed - stringPtr->numChars - + TCL_MIN_UNICHAR_GROWTH; - - attempt = needed + extra; + if (needed < (STRING_MAXCHARS - TCL_MIN_GROWTH)) { + attempt = needed + TCL_MIN_GROWTH; + } else { + attempt = STRING_MAXCHARS; + } ptr = stringAttemptRealloc(stringPtr, attempt); } } if (ptr == NULL) { - /* - * First allocation - just big enough; or last chance fallback. - */ - + /* First allocation - just big enough; or last chance fallback. */ attempt = needed; ptr = stringRealloc(stringPtr, attempt); } diff --git a/generic/tclStringRep.h b/generic/tclStringRep.h index 7f72b04..d4b6b2d 100644 --- a/generic/tclStringRep.h +++ b/generic/tclStringRep.h @@ -34,9 +34,10 @@ typedef struct { * calculated. Any other means that there is a valid * Unicode rep, or that the number of UTF bytes == * the number of chars. */ - Tcl_Size allocated; /* The amount of space actually allocated for - * the UTF-8 string (minus 1 byte for the - * termination char). */ + Tcl_Size allocated; /* The amount of space allocated for + * the UTF-8 string. Does not include nul + * terminator so actual allocation is + * (allocated+1). */ Tcl_Size maxChars; /* Max number of chars that can fit in the * space allocated for the Unicode array. */ int hasUnicode; /* Boolean determining whether the string has |
