summaryrefslogtreecommitdiffstats
path: root/generic/tclCompCmdsSZ.c
diff options
context:
space:
mode:
Diffstat (limited to 'generic/tclCompCmdsSZ.c')
-rw-r--r--generic/tclCompCmdsSZ.c25
1 files changed, 22 insertions, 3 deletions
diff --git a/generic/tclCompCmdsSZ.c b/generic/tclCompCmdsSZ.c
index b19dfc8..3d45833 100644
--- a/generic/tclCompCmdsSZ.c
+++ b/generic/tclCompCmdsSZ.c
@@ -14,7 +14,7 @@
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclCompCmdsSZ.c,v 1.7 2010/03/27 22:40:14 nijtmans Exp $
+ * RCS: @(#) $Id: tclCompCmdsSZ.c,v 1.8 2010/04/08 13:26:24 dkf Exp $
*/
#include "tclInt.h"
@@ -659,7 +659,21 @@ TclSubstCompile(
TclSubstParse(interp, bytes, numBytes, flags, &parse, &state);
- for (tokenPtr = parse.tokenPtr, endTokenPtr = tokenPtr + parse.numTokens;
+ /*
+ * Tricky point! If the first token does not result in a *guaranteed* push
+ * of a Tcl_Obj on the stack, we must push an empty object. Otherwise it
+ * is possible to get to an INST_CONCAT1 or INST_DONE without enough
+ * values on the stack, resulting in a crash. Thanks to Joe Mistachkin for
+ * identifying a script that could trigger this case.
+ */
+
+ tokenPtr = parse.tokenPtr;
+ if (tokenPtr->type != TCL_TOKEN_TEXT && tokenPtr->type != TCL_TOKEN_BS) {
+ PushLiteral(envPtr, "", 0);
+ count++;
+ }
+
+ for (endTokenPtr = tokenPtr + parse.numTokens;
tokenPtr < endTokenPtr; tokenPtr = TokenAfter(tokenPtr)) {
int length, literal, catchRange, breakJump;
char buf[TCL_UTF_MAX];
@@ -790,7 +804,11 @@ TclSubstCompile(
Tcl_Panic("TclCompileSubstCmd: bad other jump distance %d",
CurrentOffset(envPtr) - otherFixup.codeOffset);
}
- /* Pull the result to top of stack, discard options dict */
+
+ /*
+ * Pull the result to top of stack, discard options dict.
+ */
+
TclEmitInstInt4(INST_REVERSE, 2, envPtr);
TclEmitOpcode(INST_POP, envPtr);
@@ -802,6 +820,7 @@ TclSubstCompile(
* through them all. So, we now have a stack requirements estimate
* that is too low. Here we manually fix that up.
*/
+
TclAdjustStackDepth(5, envPtr);
/* OK destination */