diff options
author | apnadkarni <apnmbx-wits@yahoo.com> | 2022-11-02 15:56:42 (GMT) |
---|---|---|
committer | apnadkarni <apnmbx-wits@yahoo.com> | 2022-11-02 15:56:42 (GMT) |
commit | 0dfd2bdc9def2f625b73fa3f8ca501d68ab24f98 (patch) | |
tree | 402bba327fb562ce946625d4ecab9a96a970a9d6 /generic/tclStringObj.c | |
parent | 366778e86ecc27d557a56047f3f6d12439f67cf8 (diff) | |
download | tcl-0dfd2bdc9def2f625b73fa3f8ca501d68ab24f98.zip tcl-0dfd2bdc9def2f625b73fa3f8ca501d68ab24f98.tar.gz tcl-0dfd2bdc9def2f625b73fa3f8ca501d68ab24f98.tar.bz2 |
Bug #0f98bce669 - string repeat support for > 2**31 characters
Diffstat (limited to 'generic/tclStringObj.c')
-rw-r--r-- | generic/tclStringObj.c | 22 |
1 files changed, 17 insertions, 5 deletions
diff --git a/generic/tclStringObj.c b/generic/tclStringObj.c index cf23aab..60dfa4d 100644 --- a/generic/tclStringObj.c +++ b/generic/tclStringObj.c @@ -2933,6 +2933,7 @@ TclStringRepeat( int inPlace = flags & TCL_STRING_IN_PLACE; size_t length = 0, unichar = 0, done = 1; int binary = TclIsPureByteArray(objPtr); + size_t maxCount; /* assert (count >= 2) */ @@ -2955,12 +2956,17 @@ TclStringRepeat( if (binary) { /* Result will be pure byte array. Pre-size it */ (void)Tcl_GetByteArrayFromObj(objPtr, &length); - } else if (unichar) { + maxCount = TCL_SIZE_SMAX; + } + else if (unichar) { /* Result will be pure Tcl_UniChar array. Pre-size it. */ (void)Tcl_GetUnicodeFromObj(objPtr, &length); - } else { + maxCount = TCL_SIZE_SMAX/sizeof(Tcl_UniChar); + } + else { /* Result will be concat of string reps. Pre-size it. */ (void)Tcl_GetStringFromObj(objPtr, &length); + maxCount = TCL_SIZE_SMAX; } if (length == 0) { @@ -2968,10 +2974,14 @@ TclStringRepeat( return objPtr; } - if (count > INT_MAX/length) { + /* maxCount includes space for null */ + if (count > (maxCount-1)) { if (interp) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "max size for a Tcl value (%d bytes) exceeded", INT_MAX)); + Tcl_SetObjResult( + interp, + Tcl_ObjPrintf("max size for a Tcl value (%u" TCL_Z_MODIFIER + " bytes) exceeded", + TCL_SIZE_SMAX)); Tcl_SetErrorCode(interp, "TCL", "MEMORY", NULL); } return NULL; @@ -2982,6 +2992,7 @@ TclStringRepeat( objResultPtr = (!inPlace || Tcl_IsShared(objPtr)) ? Tcl_DuplicateObj(objPtr) : objPtr; + /* Allocate count*length space */ Tcl_SetByteArrayLength(objResultPtr, count*length); /* PANIC? */ Tcl_SetByteArrayLength(objResultPtr, length); while (count - done > done) { @@ -3049,6 +3060,7 @@ TclStringRepeat( (count - done) * length); } return objResultPtr; + } /* |