summaryrefslogtreecommitdiffstats
path: root/generic/tclStringObj.c
diff options
context:
space:
mode:
authordgp <dgp@users.sourceforge.net>2009-02-04 19:59:25 (GMT)
committerdgp <dgp@users.sourceforge.net>2009-02-04 19:59:25 (GMT)
commit3739c0af948b9cfc9ccbe00fa2764f9bb5364308 (patch)
tree5cf38fae1bb79dafda703983dd5e931a953b023e /generic/tclStringObj.c
parent49dfd861199470b98849897f9d94ad4691438d4e (diff)
downloadtcl-3739c0af948b9cfc9ccbe00fa2764f9bb5364308.zip
tcl-3739c0af948b9cfc9ccbe00fa2764f9bb5364308.tar.gz
tcl-3739c0af948b9cfc9ccbe00fa2764f9bb5364308.tar.bz2
* 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]
Diffstat (limited to 'generic/tclStringObj.c')
-rw-r--r--generic/tclStringObj.c18
1 files changed, 14 insertions, 4 deletions
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);
}
}