diff options
-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 *))); |