diff options
author | dgp <dgp@users.sourceforge.net> | 2009-02-03 18:10:22 (GMT) |
---|---|---|
committer | dgp <dgp@users.sourceforge.net> | 2009-02-03 18:10:22 (GMT) |
commit | c5b1811e0b0594c5549206669adcc79215551d09 (patch) | |
tree | 12d1bd8f1ec63712b889fe43083caa61d4c7d718 | |
parent | bc8de2fe434eaa5961793b2e00ce90e55e710433 (diff) | |
download | tcl-c5b1811e0b0594c5549206669adcc79215551d09.zip tcl-c5b1811e0b0594c5549206669adcc79215551d09.tar.gz tcl-c5b1811e0b0594c5549206669adcc79215551d09.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-03 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/tclObj.c (Tcl_GetStringFromObj): Reduce code duplication. 2009-02-02 Don Porter <dgp@users.sourceforge.net> diff --git a/generic/tclStringObj.c b/generic/tclStringObj.c index da80876..df7521d 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.81 2009/02/02 05:54:53 dgp Exp $ */ + * RCS: @(#) $Id: tclStringObj.c,v 1.82 2009/02/03 18:10:22 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); /* @@ -325,35 +327,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 = stringAlloc(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; } @@ -708,11 +684,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"); } @@ -724,6 +695,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); @@ -1006,6 +982,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; @@ -1017,20 +1008,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 = stringAlloc(uallocated); + stringPtr->numChars = numChars; stringPtr->uallocated = uallocated; stringPtr->hasUnicode = (numChars > 0); @@ -1038,9 +1023,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); } /* |