summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordkf <donal.k.fellows@manchester.ac.uk>2016-03-20 20:40:07 (GMT)
committerdkf <donal.k.fellows@manchester.ac.uk>2016-03-20 20:40:07 (GMT)
commit01d1cdb5e8789884ae310c5e38fb976559157460 (patch)
tree0c82168b2d4fedfd1bf0a71ebfdc1f421269747a
parentbfa7cb3c5d224a86a6136bc063018638eb3b9a0b (diff)
downloadtcl-01d1cdb5e8789884ae310c5e38fb976559157460.zip
tcl-01d1cdb5e8789884ae310c5e38fb976559157460.tar.gz
tcl-01d1cdb5e8789884ae310c5e38fb976559157460.tar.bz2
[1af8de570511] Fix crash in [string replace] caused by cut-n-paste.
-rw-r--r--generic/tclExecute.c35
-rw-r--r--tests/stringComp.test10
2 files changed, 23 insertions, 22 deletions
diff --git a/generic/tclExecute.c b/generic/tclExecute.c
index dacc9e2..c43cc40 100644
--- a/generic/tclExecute.c
+++ b/generic/tclExecute.c
@@ -5737,6 +5737,17 @@ TEBCresume(
if (length3 - 1 == toIdx - fromIdx) {
unsigned char *bytes1, *bytes2;
+ /*
+ * Flush the info in the string internal rep that refers to the
+ * about-to-be-invalidated UTF-8 rep. This sets the 'allocated'
+ * field of the String structure to 0 to indicate that a new
+ * buffer needs to be allocated. This assumes that the value is
+ * already of tclStringTypePtr type, which should be true provided
+ * we call it after Tcl_GetUnicodeFromObj.
+ */
+#define MarkStringInternalRepForFlush(objPtr) \
+ (((int *) ((objPtr)->internalRep.twoPtrValue.ptr1))[1] = 0)
+
if (Tcl_IsShared(valuePtr)) {
objResultPtr = Tcl_DuplicateObj(valuePtr);
if (TclIsPureByteArray(objResultPtr)
@@ -5749,17 +5760,7 @@ TEBCresume(
ustring2 = Tcl_GetUnicodeFromObj(value3Ptr, NULL);
memcpy(ustring1 + fromIdx, ustring2,
length3 * sizeof(Tcl_UniChar));
-
- /*
- * Magic! Flush the info in the string internal rep that
- * refers to the about-to-be-invalidated UTF-8 rep. This
- * sets the 'allocated' field of the String structure to 0
- * to indicate that a new buffer needs to be allocated.
- * This is safe; we know we've got a tclStringTypePtr set
- * at this point (post Tcl_GetUnicodeFromObj).
- */
-
- ((int *) objResultPtr->internalRep.twoPtrValue.ptr1)[1] = 0;
+ MarkStringInternalRepForFlush(objResultPtr);
}
Tcl_InvalidateStringRep(objResultPtr);
TclDecrRefCount(value3Ptr);
@@ -5776,17 +5777,7 @@ TEBCresume(
ustring2 = Tcl_GetUnicodeFromObj(value3Ptr, NULL);
memcpy(ustring1 + fromIdx, ustring2,
length3 * sizeof(Tcl_UniChar));
-
- /*
- * Magic! Flush the info in the string internal rep that
- * refers to the about-to-be-invalidated UTF-8 rep. This
- * sets the 'allocated' field of the String structure to 0
- * to indicate that a new buffer needs to be allocated.
- * This is safe; we know we've got a tclStringTypePtr set
- * at this point (post Tcl_GetUnicodeFromObj).
- */
-
- ((int *) objResultPtr->internalRep.twoPtrValue.ptr1)[1] = 0;
+ MarkStringInternalRepForFlush(valuePtr);
}
Tcl_InvalidateStringRep(valuePtr);
TclDecrRefCount(value3Ptr);
diff --git a/tests/stringComp.test b/tests/stringComp.test
index a66525e..140a270 100644
--- a/tests/stringComp.test
+++ b/tests/stringComp.test
@@ -728,6 +728,16 @@ test stringComp-14.3 {Bug 0dca3bfa8f} {
expr {$arg ne $argCopy}
}} abcde
} 1
+test stringComp-14.4 {Bug 1af8de570511} {
+ apply {{x y} {
+ # Generate an unshared string value
+ set val ""
+ for { set i 0 } { $i < $x } { incr i } {
+ set val [format "0%s" $val]
+ }
+ string replace $val[unset val] 1 1 $y
+ }} 4 x
+} 0x00
## string tolower
## not yet bc