diff options
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | generic/tclCmdIL.c | 24 |
2 files changed, 26 insertions, 4 deletions
@@ -1,3 +1,9 @@ +2008-09-27 Donal K. Fellows <dkf@users.sf.net> + + * generic/tclCmdIL.c (Tcl_LrepeatObjCmd): Improve the handling of the + case where the combination of number of elements and repeat count + causes the resulting list to be too large. [Bug 2130992] + 2008-09-26 Don Porter <dgp@users.sourceforge.net> TIP #323 IMPLEMENTATION (partial) diff --git a/generic/tclCmdIL.c b/generic/tclCmdIL.c index 99a6cb5..73144f8 100644 --- a/generic/tclCmdIL.c +++ b/generic/tclCmdIL.c @@ -16,7 +16,7 @@ * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tclCmdIL.c,v 1.153 2008/09/26 21:05:57 dgp Exp $ + * RCS: @(#) $Id: tclCmdIL.c,v 1.154 2008/09/27 14:16:42 dkf Exp $ */ #include "tclInt.h" @@ -2443,7 +2443,7 @@ Tcl_LrepeatObjCmd( register Tcl_Obj *const objv[]) /* The argument objects. */ { - int elementCount, i; + int elementCount, i, totalElems; Tcl_Obj *listPtr, **dataArray; List *listRepPtr; @@ -2473,12 +2473,28 @@ Tcl_LrepeatObjCmd( objv += 2; /* + * Final sanity check. Total number of elements must fit in a signed + * integer. We also limit the number of elements to 512M-1 so allocations + * on 32-bit machines are guaranteed to be less than 2GB! [Bug 2130992] + */ + + totalElems = objc * elementCount; + if (totalElems/objc != elementCount || totalElems/elementCount != objc) { + Tcl_AppendResult(interp, "too many elements in result list", NULL); + return TCL_ERROR; + } + if (totalElems >= 0x20000000) { + Tcl_AppendResult(interp, "too many elements in result list", NULL); + return TCL_ERROR; + } + + /* * Get an empty list object that is allocated large enough to hold each * init value elementCount times. */ - listPtr = Tcl_NewListObj(elementCount*objc, NULL); - listRepPtr = (List *) listPtr->internalRep.twoPtrValue.ptr1; + listPtr = Tcl_NewListObj(totalElems, NULL); + listRepPtr = listPtr->internalRep.twoPtrValue.ptr1; listRepPtr->elemCount = elementCount*objc; dataArray = &listRepPtr->elements; |