summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--generic/tcl.h1
-rw-r--r--generic/tclInt.h5
-rw-r--r--generic/tclStringObj.c14
3 files changed, 15 insertions, 5 deletions
diff --git a/generic/tcl.h b/generic/tcl.h
index be39d2f..706c5f1 100644
--- a/generic/tcl.h
+++ b/generic/tcl.h
@@ -668,7 +668,6 @@ typedef size_t Tcl_Size;
#else
typedef int Tcl_Size;
#endif
-#define TCL_SIZE_SMAX ((((Tcl_Size) 1) << ((8*sizeof(Tcl_Size)) - 1)) - 1)
typedef struct Tcl_Obj {
diff --git a/generic/tclInt.h b/generic/tclInt.h
index a7985f7..39ddef2 100644
--- a/generic/tclInt.h
+++ b/generic/tclInt.h
@@ -105,6 +105,11 @@
#endif
/*
+ * Maximum *signed* value that can be stored in a Tcl_Size type.
+ */
+#define TCL_SIZE_SMAX ((((Tcl_Size) 1) << ((8*sizeof(Tcl_Size)) - 1)) - 1)
+
+/*
* Macros used to cast between pointers and integers (e.g. when storing an int
* in ClientData), on 64-bit architectures they avoid gcc warning about "cast
* to/from pointer from/to integer of different size".
diff --git a/generic/tclStringObj.c b/generic/tclStringObj.c
index 60dfa4d..008ece9 100644
--- a/generic/tclStringObj.c
+++ b/generic/tclStringObj.c
@@ -3089,7 +3089,7 @@ TclStringCat(
{
Tcl_Obj *objResultPtr, * const *ov;
int oc, binary = 1;
- size_t length = 0;
+ size_t length = 0;
int allowUniChar = 1, requestUniChar = 0, forceUniChar = 0;
int first = objc - 1; /* Index of first value possibly not empty */
int last = 0; /* Index of last value possibly not empty */
@@ -3171,6 +3171,9 @@ TclStringCat(
if (length == 0) {
first = last;
}
+ if (length > (TCL_SIZE_SMAX-numBytes)) {
+ goto overflow;
+ }
length += numBytes;
}
}
@@ -3194,6 +3197,9 @@ TclStringCat(
if (length == 0) {
first = last;
}
+ if (length > ((TCL_SIZE_SMAX/sizeof(Tcl_UniChar))-numChars)) {
+ goto overflow;
+ }
length += numChars;
}
}
@@ -3258,7 +3264,7 @@ TclStringCat(
if (numBytes) {
first = last;
}
- } else if (numBytes + length > (size_t)INT_MAX) {
+ } else if (numBytes > (TCL_SIZE_SMAX - length)) {
goto overflow;
}
length += numBytes;
@@ -3275,7 +3281,7 @@ TclStringCat(
numBytes = objPtr->length;
if (numBytes) {
last = objc - oc;
- if (numBytes + length > (size_t)INT_MAX) {
+ if (numBytes > (TCL_SIZE_SMAX - length)) {
goto overflow;
}
length += numBytes;
@@ -3434,7 +3440,7 @@ TclStringCat(
overflow:
if (interp) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
- "max size for a Tcl value (%d bytes) exceeded", INT_MAX));
+ "max size for a Tcl value (%u" TCL_Z_MODIFIER " bytes) exceeded", TCL_SIZE_SMAX));
Tcl_SetErrorCode(interp, "TCL", "MEMORY", NULL);
}
return NULL;