From 3739c0af948b9cfc9ccbe00fa2764f9bb5364308 Mon Sep 17 00:00:00 2001 From: dgp Date: Wed, 4 Feb 2009 19:59:25 +0000 Subject: * generic/tclStringObj.c: Added overflow protections to the AppendUtfToUtfRep routine to either avoid invalid arguments and crashes, or to replace them with controlled panics. [Bug 2561794] --- ChangeLog | 4 ++++ generic/tclStringObj.c | 18 ++++++++++++++---- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index cc51b8d..9136545 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2009-02-04 Don Porter + * generic/tclStringObj.c: Added overflow protections to the + AppendUtfToUtfRep routine to either avoid invalid arguments and + crashes, or to replace them with controlled panics. [Bug 2561794] + * generic/tclCmdMZ.c: Prevent crashes due to int overflow of the length of the result of [string repeat]. [Bug 2561746] diff --git a/generic/tclStringObj.c b/generic/tclStringObj.c index df7521d..6171db6 100644 --- a/generic/tclStringObj.c +++ b/generic/tclStringObj.c @@ -33,7 +33,7 @@ * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tclStringObj.c,v 1.82 2009/02/03 18:10:22 dgp Exp $ */ + * RCS: @(#) $Id: tclStringObj.c,v 1.83 2009/02/04 19:59:25 dgp Exp $ */ #include "tclInt.h" #include "tommath.h" @@ -879,7 +879,7 @@ Tcl_AttemptSetObjLength( * Check that we're not extending a pure unicode string. */ - if (length > (int) stringPtr->allocated && + if ((size_t)length > stringPtr->allocated && (objPtr->bytes != NULL || stringPtr->hasUnicode == 0)) { char *newBytes; @@ -1477,6 +1477,9 @@ AppendUtfToUtfRep( */ oldLength = objPtr->length; + if (numBytes > INT_MAX - oldLength) { + Tcl_Panic("max size for a Tcl value (%d bytes) exceeded", INT_MAX); + } newLength = numBytes + oldLength; stringPtr = GET_STRING(objPtr); @@ -1490,8 +1493,15 @@ AppendUtfToUtfRep( */ if (Tcl_AttemptSetObjLength(objPtr, 2 * newLength) == 0) { - Tcl_SetObjLength(objPtr, - newLength + numBytes + TCL_GROWTH_MIN_ALLOC); + /* + * Take care computing the amount of modest growth to avoid + * overflow into invalid argument values for Tcl_SetObjLength. + */ + unsigned int limit = INT_MAX - newLength; + unsigned int extra = numBytes + TCL_GROWTH_MIN_ALLOC; + int growth = (int) ((extra > limit) ? limit : extra); + + Tcl_SetObjLength(objPtr, newLength + growth); } } -- cgit v0.12