diff options
author | dgp <dgp@users.sourceforge.net> | 2015-07-29 14:56:20 (GMT) |
---|---|---|
committer | dgp <dgp@users.sourceforge.net> | 2015-07-29 14:56:20 (GMT) |
commit | f9980d463faea1c016549089f3ef8fe166a41529 (patch) | |
tree | 0d5f0dd890359f576e07d1eeebe65a26f81acf78 /generic | |
parent | e863ec8015f6bff1a8017b6557ba0b7cb9d7d039 (diff) | |
parent | ec20498ab74fd4c48e24dcc7ecc9ff9e36b3ba72 (diff) | |
download | tcl-f9980d463faea1c016549089f3ef8fe166a41529.zip tcl-f9980d463faea1c016549089f3ef8fe166a41529.tar.gz tcl-f9980d463faea1c016549089f3ef8fe166a41529.tar.bz2 |
[3e7eca8c8c] Prevent overflow in size values passed to allocators.
Diffstat (limited to 'generic')
-rw-r--r-- | generic/tclLiteral.c | 22 |
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; |