summaryrefslogtreecommitdiffstats
path: root/generic/tclLiteral.c
diff options
context:
space:
mode:
authordgp <dgp@users.sourceforge.net>2015-07-29 14:54:13 (GMT)
committerdgp <dgp@users.sourceforge.net>2015-07-29 14:54:13 (GMT)
commitec20498ab74fd4c48e24dcc7ecc9ff9e36b3ba72 (patch)
tree3a178b2e98acbb2d014951b7929af316e9b67ddc /generic/tclLiteral.c
parent96585a0ae4cf7d41417955b92a4491510101b38e (diff)
downloadtcl-ec20498ab74fd4c48e24dcc7ecc9ff9e36b3ba72.zip
tcl-ec20498ab74fd4c48e24dcc7ecc9ff9e36b3ba72.tar.gz
tcl-ec20498ab74fd4c48e24dcc7ecc9ff9e36b3ba72.tar.bz2
[3e7eca8c8c] Prevent overflow in size values passed to allocators.
Diffstat (limited to 'generic/tclLiteral.c')
-rw-r--r--generic/tclLiteral.c22
1 files changed, 19 insertions, 3 deletions
diff --git a/generic/tclLiteral.c b/generic/tclLiteral.c
index 09540ea..6a617b0 100644
--- a/generic/tclLiteral.c
+++ b/generic/tclLiteral.c
@@ -682,16 +682,22 @@ ExpandLocalLiteralArray(
LiteralEntry *currArrayPtr = envPtr->literalArrayPtr;
LiteralEntry *newArrayPtr;
int i;
+ unsigned int newSize = (currBytes <= UINT_MAX / 2) ? 2*currBytes : UINT_MAX;
+
+ if (currBytes == newSize) {
+ Tcl_Panic("max size of Tcl literal array (%d literals) exceeded",
+ currElems);
+ }
if (envPtr->mallocedLiteralArray) {
newArrayPtr = (LiteralEntry *) ckrealloc(
- (char *)currArrayPtr, 2 * currBytes);
+ (char *)currArrayPtr, newSize);
} else {
/*
* envPtr->literalArrayPtr isn't a ckalloc'd pointer, so we must
* code a ckrealloc equivalent for ourselves
*/
- newArrayPtr = (LiteralEntry *) ckalloc(2 * currBytes);
+ newArrayPtr = (LiteralEntry *) ckalloc(newSize);
memcpy(newArrayPtr, currArrayPtr, currBytes);
envPtr->mallocedLiteralArray = 1;
}
@@ -716,7 +722,7 @@ ExpandLocalLiteralArray(
}
envPtr->literalArrayPtr = newArrayPtr;
- envPtr->literalArrayEnd = (2 * currElems);
+ envPtr->literalArrayEnd = newSize / sizeof(LiteralEntry);
}
/*
@@ -886,6 +892,16 @@ RebuildLiteralTable(
* constants for new array size.
*/
+ if (oldSize > UINT_MAX/(4 * sizeof(LiteralEntry *))) {
+ /*
+ * Memory allocator limitations will not let us create the
+ * next larger table size. Best option is to limp along
+ * with what we have.
+ */
+
+ return;
+ }
+
tablePtr->numBuckets *= 4;
tablePtr->buckets = (LiteralEntry **) ckalloc((unsigned)
(tablePtr->numBuckets * sizeof(LiteralEntry *)));