diff options
-rw-r--r-- | generic/tclStringObj.c | 35 |
1 files changed, 18 insertions, 17 deletions
diff --git a/generic/tclStringObj.c b/generic/tclStringObj.c index a4c242a..c1c15f2 100644 --- a/generic/tclStringObj.c +++ b/generic/tclStringObj.c @@ -2897,7 +2897,7 @@ TclStringCatObjv( if (binary) { /* Result will be pure byte array. Pre-size it */ ov = objv; oc = objc; - while (oc-- && (length >= 0)) { + while (oc--) { objPtr = *ov++; if (objPtr->bytes == NULL) { @@ -2909,14 +2909,16 @@ TclStringCatObjv( if (length == 0) { first = last; } + if ((length += numBytes) < 0) { + break; /* overflow */ + } } - length += numBytes; } } } else if (allowUniChar && requestUniChar) { /* Result will be pure Tcl_UniChar array. Pre-size it. */ ov = objv; oc = objc; - while (oc-- && (length >= 0)) { + while (oc--) { objPtr = *ov++; if ((objPtr->bytes == NULL) || (objPtr->length)) { @@ -2929,13 +2931,15 @@ TclStringCatObjv( first = last; } } - length += numChars; + if ((length += numChars) < 0) { + break; /* overflow */ + } } } } else { /* Result will be concat of string reps. Pre-size it. */ ov = objv; oc = objc; - while (oc-- && (length >= 0)) { + while (oc--) { int numBytes; objPtr = *ov++; @@ -2946,11 +2950,19 @@ TclStringCatObjv( if (length == 0) { first = last; } + if ((length += numBytes) < 0) { + break; /* overflow */ + } } - length += numBytes; } } + if (last == first || length == 0) { + /* Only one non-empty value or zero length; return first */ + *objPtrPtr = objv[first]; + return TCL_OK; + } + if (length < 0) { if (interp) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( @@ -2960,17 +2972,6 @@ TclStringCatObjv( return TCL_ERROR; } - if (length == 0) { - /* Total length of zero means every value has length zero */ - *objPtrPtr = objv[0]; - return TCL_OK; - } - if (last == first) { - /* Only one non-empty value; return it */ - *objPtrPtr = objv[first]; - return TCL_OK; - } - objv += first; objc = (last - first + 1); if (binary) { |