summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordgp <dgp@users.sourceforge.net>2018-01-27 01:45:27 (GMT)
committerdgp <dgp@users.sourceforge.net>2018-01-27 01:45:27 (GMT)
commit175fe8c23f5d96a8cb4ecde93e7407e48c49da6d (patch)
tree76412a23080cba29eec8f410b5d8380b58c6c141
parentd20d1e603b71ac5bc0fb1074309917b60609e1b5 (diff)
parenta0c6bf8d922f9e7853a161b064103518dddd4612 (diff)
downloadtcl-175fe8c23f5d96a8cb4ecde93e7407e48c49da6d.zip
tcl-175fe8c23f5d96a8cb4ecde93e7407e48c49da6d.tar.gz
tcl-175fe8c23f5d96a8cb4ecde93e7407e48c49da6d.tar.bz2
Fix segfault due to shimmering in [join $l $l]. (Test join-4.1).
-rw-r--r--generic/tclCmdIL.c5
-rw-r--r--tests/join.test5
2 files changed, 8 insertions, 2 deletions
diff --git a/generic/tclCmdIL.c b/generic/tclCmdIL.c
index b41d312..77b8434 100644
--- a/generic/tclCmdIL.c
+++ b/generic/tclCmdIL.c
@@ -2160,7 +2160,7 @@ Tcl_JoinObjCmd(
int objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* The argument objects. */
{
- int listLen;
+ int length, listLen;
Tcl_Obj *resObjPtr = NULL, *joinObjPtr, **elemPtrs;
if ((objc < 2) || (objc > 3)) {
@@ -2191,7 +2191,8 @@ Tcl_JoinObjCmd(
joinObjPtr = (objc == 2) ? Tcl_NewStringObj(" ", 1) : objv[2];
Tcl_IncrRefCount(joinObjPtr);
- if (Tcl_GetCharLength(joinObjPtr) == 0) {
+ (void) Tcl_GetStringFromObj(joinObjPtr, &length);
+ if (length == 0) {
TclStringCatObjv(interp, /* inPlace */ 0, listLen, elemPtrs,
&resObjPtr);
} else {
diff --git a/tests/join.test b/tests/join.test
index 4abe233..4aeb093 100644
--- a/tests/join.test
+++ b/tests/join.test
@@ -45,6 +45,11 @@ test join-3.1 {joinString is binary ok} {
test join-3.2 {join is binary ok} {
string length [join "a\0b a\0b a\0b"]
} 11
+
+test join-4.1 {shimmer segfault prevention} {
+ set l {0 0}
+ join $l $l
+} {00 00}
# cleanup
::tcltest::cleanupTests