summaryrefslogtreecommitdiffstats
path: root/generic/tclStringObj.c
diff options
context:
space:
mode:
authorapnadkarni <apnmbx-wits@yahoo.com>2022-11-02 15:56:42 (GMT)
committerapnadkarni <apnmbx-wits@yahoo.com>2022-11-02 15:56:42 (GMT)
commit0dfd2bdc9def2f625b73fa3f8ca501d68ab24f98 (patch)
tree402bba327fb562ce946625d4ecab9a96a970a9d6 /generic/tclStringObj.c
parent366778e86ecc27d557a56047f3f6d12439f67cf8 (diff)
downloadtcl-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.c22
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;
+
}
/*