diff options
author | dgp <dgp@users.sourceforge.net> | 2015-07-29 14:54:13 (GMT) |
---|---|---|
committer | dgp <dgp@users.sourceforge.net> | 2015-07-29 14:54:13 (GMT) |
commit | ec20498ab74fd4c48e24dcc7ecc9ff9e36b3ba72 (patch) | |
tree | 3a178b2e98acbb2d014951b7929af316e9b67ddc /generic | |
parent | 96585a0ae4cf7d41417955b92a4491510101b38e (diff) | |
download | tcl-ec20498ab74fd4c48e24dcc7ecc9ff9e36b3ba72.zip tcl-ec20498ab74fd4c48e24dcc7ecc9ff9e36b3ba72.tar.gz tcl-ec20498ab74fd4c48e24dcc7ecc9ff9e36b3ba72.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 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 *))); |