summaryrefslogtreecommitdiffstats
path: root/generic/tclStringObj.c
diff options
context:
space:
mode:
authordgp <dgp@users.sourceforge.net>2009-02-16 04:06:07 (GMT)
committerdgp <dgp@users.sourceforge.net>2009-02-16 04:06:07 (GMT)
commit83b89e4cb82d0744ad11a21b568e43fc6398f605 (patch)
treeea2e98682595184a07576b9fa957f3ccb18537ab /generic/tclStringObj.c
parent53a6c6e15b5a20bc8c7bb870aba701855f8da484 (diff)
downloadtcl-83b89e4cb82d0744ad11a21b568e43fc6398f605.zip
tcl-83b89e4cb82d0744ad11a21b568e43fc6398f605.tar.gz
tcl-83b89e4cb82d0744ad11a21b568e43fc6398f605.tar.bz2
* generic/tclStringObj.c: Added protections from invalid memory
* generic/tclTestObj.c: accesses when we append (some part of) * tests/stringObj.test: a Tcl_Obj to itself. Added the appendself and appendself2 subcommands to the [teststringobj] testing command and added tests to the test suite. [Bug 2603158]
Diffstat (limited to 'generic/tclStringObj.c')
-rw-r--r--generic/tclStringObj.c36
1 files changed, 32 insertions, 4 deletions
diff --git a/generic/tclStringObj.c b/generic/tclStringObj.c
index 1bfe70d..ecea7be 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.108 2009/02/15 23:13:11 dgp Exp $ */
+ * RCS: @(#) $Id: tclStringObj.c,v 1.109 2009/02/16 04:06:07 dgp Exp $ */
#include "tclInt.h"
#include "tommath.h"
@@ -1241,8 +1241,6 @@ Tcl_AppendObjToObj(
* appendObjPtr and append it.
*/
- /* TODO: Check that append to self works */
-
if (stringPtr->hasUnicode && stringPtr->numChars > 0) {
/*
* If appendObjPtr is not of the "String" type, don't convert it.
@@ -1266,7 +1264,6 @@ Tcl_AppendObjToObj(
* characters in the final (appended-to) object.
*/
- /* TODO: Check that append to self works */
bytes = TclGetStringFromObj(appendObjPtr, &length);
numChars = stringPtr->numChars;
@@ -1332,6 +1329,16 @@ AppendUnicodeToUnicodeRep(
}
if (numChars >= stringPtr->maxChars) {
+ /*
+ * Protect against case where unicode points into the existing
+ * stringPtr->unicode array. Force it to follow any relocations
+ * due to the reallocs below.
+ */
+ int offset = -1;
+ if (unicode >= stringPtr->unicode
+ && unicode <= stringPtr->unicode + stringPtr->maxChars) {
+ offset = unicode - stringPtr->unicode;
+ }
/* TODO: overflow check */
stringPtr->maxChars = 2 * numChars;
@@ -1344,6 +1351,11 @@ AppendUnicodeToUnicodeRep(
}
stringPtr = tmpString;
SET_STRING(objPtr, stringPtr);
+
+ /* Relocate unicode if needed; see above. */
+ if (offset >= 0) {
+ unicode = stringPtr->unicode + offset;
+ }
}
/*
@@ -1484,6 +1496,17 @@ AppendUtfToUtfRep(
* explanation of this growth algorithm.
*/
+ /*
+ * Protect against case where unicode points into the existing
+ * stringPtr->unicode array. Force it to follow any relocations
+ * due to the reallocs below.
+ */
+ int offset = -1;
+ if (bytes >= objPtr->bytes
+ && bytes <= objPtr->bytes + objPtr->length) {
+ offset = bytes - objPtr->bytes;
+ }
+
if (Tcl_AttemptSetObjLength(objPtr, 2 * newLength) == 0) {
/*
* Take care computing the amount of modest growth to avoid
@@ -1495,6 +1518,11 @@ AppendUtfToUtfRep(
Tcl_SetObjLength(objPtr, newLength + growth);
}
+
+ /* Relocate bytes if needed; see above. */
+ if (offset >= 0) {
+ bytes = objPtr->bytes + offset;
+ }
}
/*