diff options
author | dgp <dgp@users.sourceforge.net> | 2009-02-04 20:21:40 (GMT) |
---|---|---|
committer | dgp <dgp@users.sourceforge.net> | 2009-02-04 20:21:40 (GMT) |
commit | 14382184e4298588141bd84830147afe007d33db (patch) | |
tree | 92a9ac1c7c9933326203668fb602a581664b9c96 | |
parent | 557a19a96c598d8b25e9e72134ea69030946a310 (diff) | |
download | tcl-14382184e4298588141bd84830147afe007d33db.zip tcl-14382184e4298588141bd84830147afe007d33db.tar.gz tcl-14382184e4298588141bd84830147afe007d33db.tar.bz2 |
* generic/tclStringObj.c (SetUnicodeObj): Corrected failure of
Tcl_SetUnicodeObj() to panic on a shared object. [Bug 2561488]. Also
factored out common code to reduce duplication.
-rw-r--r-- | ChangeLog | 4 | ||||
-rw-r--r-- | generic/tclStringObj.c | 71 |
2 files changed, 32 insertions, 43 deletions
@@ -1,5 +1,9 @@ 2009-02-04 Don Porter <dgp@users.sourceforge.net> + * generic/tclStringObj.c (SetUnicodeObj): Corrected failure of + Tcl_SetUnicodeObj() to panic on a shared object. [Bug 2561488]. Also + factored out common code to reduce duplication. + * 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 21c2e85..90aaf37 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.70.2.3 2009/01/09 15:12:23 dgp Exp $ */ + * RCS: @(#) $Id: tclStringObj.c,v 1.70.2.4 2009/02/04 20:21:41 dgp Exp $ */ #include "tclInt.h" #include "tommath.h" @@ -57,6 +57,8 @@ static void FreeStringInternalRep(Tcl_Obj *objPtr); static void DupStringInternalRep(Tcl_Obj *objPtr, Tcl_Obj *copyPtr); static int SetStringFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr); +static void SetUnicodeObj(Tcl_Obj *objPtr, + const Tcl_UniChar *unicode, int numChars); static void UpdateStringOfString(Tcl_Obj *objPtr); /* @@ -312,35 +314,9 @@ Tcl_NewUnicodeObj( * string. */ { Tcl_Obj *objPtr; - String *stringPtr; - size_t uallocated; - - if (numChars < 0) { - numChars = 0; - if (unicode) { - while (unicode[numChars] != 0) { - numChars++; - } - } - } - uallocated = STRING_UALLOC(numChars); - - /* - * Create a new obj with an invalid string rep. - */ TclNewObj(objPtr); - Tcl_InvalidateStringRep(objPtr); - objPtr->typePtr = &tclStringType; - - stringPtr = (String *) ckalloc(STRING_SIZE(uallocated)); - stringPtr->numChars = numChars; - stringPtr->uallocated = uallocated; - stringPtr->hasUnicode = (numChars > 0); - stringPtr->allocated = 0; - memcpy(stringPtr->unicode, unicode, uallocated); - stringPtr->unicode[numChars] = 0; - SET_STRING(objPtr, stringPtr); + SetUnicodeObj(objPtr, unicode, numChars); return objPtr; } @@ -695,11 +671,6 @@ Tcl_SetStringObj( * when initializing the object. If negative, * use bytes up to the first NUL byte.*/ { - /* - * Free any old string rep, then set the string rep to a copy of the - * length bytes starting at "bytes". - */ - if (Tcl_IsShared(objPtr)) { Tcl_Panic("%s called with shared object", "Tcl_SetStringObj"); } @@ -711,6 +682,11 @@ Tcl_SetStringObj( TclFreeIntRep(objPtr); objPtr->typePtr = NULL; + /* + * Free any old string rep, then set the string rep to a copy of the + * length bytes starting at "bytes". + */ + Tcl_InvalidateStringRep(objPtr); if (length < 0) { length = (bytes? strlen(bytes) : 0); @@ -981,6 +957,21 @@ Tcl_SetUnicodeObj( int numChars) /* Number of characters in the unicode * string. */ { + if (Tcl_IsShared(objPtr)) { + Tcl_Panic("%s called with shared object", "Tcl_SetUnicodeObj"); + } + TclFreeIntRep(objPtr); + SetUnicodeObj(objPtr, unicode, numChars); +} + +static void +SetUnicodeObj( + Tcl_Obj *objPtr, /* The object to set the string of. */ + const Tcl_UniChar *unicode, /* The unicode string used to initialize the + * object. */ + int numChars) /* Number of characters in the unicode + * string. */ +{ String *stringPtr; size_t uallocated; @@ -992,20 +983,14 @@ Tcl_SetUnicodeObj( } } } - uallocated = STRING_UALLOC(numChars); - - /* - * Free the internal rep if one exists, and invalidate the string rep. - */ - - TclFreeIntRep(objPtr); - objPtr->typePtr = &tclStringType; /* * Allocate enough space for the String structure + Unicode string. */ + uallocated = STRING_UALLOC(numChars); stringPtr = (String *) ckalloc(STRING_SIZE(uallocated)); + stringPtr->numChars = numChars; stringPtr->uallocated = uallocated; stringPtr->hasUnicode = (numChars > 0); @@ -1013,9 +998,9 @@ Tcl_SetUnicodeObj( memcpy(stringPtr->unicode, unicode, uallocated); stringPtr->unicode[numChars] = 0; - SET_STRING(objPtr, stringPtr); Tcl_InvalidateStringRep(objPtr); - return; + objPtr->typePtr = &tclStringType; + SET_STRING(objPtr, stringPtr); } /* |