summaryrefslogtreecommitdiffstats
path: root/generic/tclLiteral.c
diff options
context:
space:
mode:
authordgp <dgp@users.sourceforge.net>2015-07-29 14:56:20 (GMT)
committerdgp <dgp@users.sourceforge.net>2015-07-29 14:56:20 (GMT)
commitf9980d463faea1c016549089f3ef8fe166a41529 (patch)
tree0d5f0dd890359f576e07d1eeebe65a26f81acf78 /generic/tclLiteral.c
parente863ec8015f6bff1a8017b6557ba0b7cb9d7d039 (diff)
parentec20498ab74fd4c48e24dcc7ecc9ff9e36b3ba72 (diff)
downloadtcl-f9980d463faea1c016549089f3ef8fe166a41529.zip
tcl-f9980d463faea1c016549089f3ef8fe166a41529.tar.gz
tcl-f9980d463faea1c016549089f3ef8fe166a41529.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 2b0cc7e..dc8770d 100644
--- a/generic/tclLiteral.c
+++ b/generic/tclLiteral.c
@@ -717,16 +717,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 = ckrealloc(currArrayPtr, 2 * currBytes);
+ newArrayPtr = ckrealloc(currArrayPtr, newSize);
} else {
/*
* envPtr->literalArrayPtr isn't a ckalloc'd pointer, so we must
* code a ckrealloc equivalent for ourselves.
*/
- newArrayPtr = ckalloc(2 * currBytes);
+ newArrayPtr = ckalloc(newSize);
memcpy(newArrayPtr, currArrayPtr, currBytes);
envPtr->mallocedLiteralArray = 1;
}
@@ -751,7 +757,7 @@ ExpandLocalLiteralArray(
}
envPtr->literalArrayPtr = newArrayPtr;
- envPtr->literalArrayEnd = (2 * currElems);
+ envPtr->literalArrayEnd = newSize / sizeof(LiteralEntry);
}
/*
@@ -942,6 +948,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 = ckalloc(tablePtr->numBuckets * sizeof(LiteralEntry*));
for (count=tablePtr->numBuckets, newChainPtr=tablePtr->buckets;