From c91b19f7bac0008bb4b74e40096663a5035c7b19 Mon Sep 17 00:00:00 2001 From: dkf Date: Sat, 27 Sep 2008 14:16:38 +0000 Subject: Fix [Bug 2130992]. --- ChangeLog | 6 ++++++ generic/tclCmdIL.c | 24 ++++++++++++++++++++---- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index b45d8e5..19043f7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2008-09-27 Donal K. Fellows + + * 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 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; -- cgit v0.12