Tcl Source Code

Artifact [70b44dacc6]
Login

Artifact 70b44dacc6970d06a73b65a683093ea46a1890c8:

Attachment "subst.patch2" to ticket [495207ffff] added by msofer 2002-02-26 06:11:21.
Index: generic/tclBasic.c
===================================================================
RCS file: /cvsroot/tcl/tcl/generic/tclBasic.c,v
retrieving revision 1.47
diff -u -r1.47 tclBasic.c
--- generic/tclBasic.c	15 Feb 2002 14:28:48 -0000	1.47
+++ generic/tclBasic.c	25 Feb 2002 23:04:48 -0000
@@ -3478,8 +3478,15 @@
     Tcl_Obj *staticObjArray[NUM_STATIC_OBJS], **objv;
     Tcl_Token *tokenPtr;
     int i, code, commandLength, bytesLeft, nested;
-    CallFrame *savedVarFramePtr;	/* Saves old copy of iPtr->varFramePtr
-					 * in case TCL_EVAL_GLOBAL was set. */
+    CallFrame *savedVarFramePtr;   /* Saves old copy of iPtr->varFramePtr
+				    * in case TCL_EVAL_GLOBAL was set. */
+    
+    /* For nested scripts, this variable will be set to point to the first 
+     * char after the end of the script - needed only to compare pointers,
+     * nothing will be read nor written there. 
+     */
+
+    char *onePast = NULL;
 
     /*
      * The variables below keep track of how much state has been
@@ -3509,6 +3516,7 @@
     bytesLeft = numBytes;
     if (iPtr->evalFlags & TCL_BRACKET_TERM) {
 	nested = 1;
+	onePast = script + numBytes;
     } else {
 	nested = 0;
     }
@@ -3520,6 +3528,19 @@
 	    goto error;
 	}
 	gotParse = 1; 
+
+	/*
+	 * A nested script can only terminate in ']'. If the script is not 
+	 * nested, onePast is NULL and the second test is not performed.
+	 */
+
+	next = parse.commandStart + parse.commandSize;
+	if ((next == onePast) && (onePast[-1] != ']')) {
+	    Tcl_SetObjResult(interp, Tcl_NewStringObj("missing close-bracket", -1));
+	    code = TCL_ERROR;
+	    goto error;
+	}
+
 	if (parse.numWords > 0) {
 	    /*
 	     * Generate an array of objects for the words of the command.
@@ -3572,7 +3593,6 @@
 	 * Advance to the next command in the script.
 	 */
 
-	next = parse.commandStart + parse.commandSize;
 	bytesLeft -= next - p;
 	p = next;
 	Tcl_FreeParse(&parse);
Index: tests/subst.test
===================================================================
RCS file: /cvsroot/tcl/tcl/tests/subst.test,v
retrieving revision 1.9
diff -u -r1.9 subst.test
--- tests/subst.test	12 Jul 2001 13:15:09 -0000	1.9
+++ tests/subst.test	25 Feb 2002 23:04:49 -0000
@@ -82,6 +82,18 @@
 test subst-5.4 {command substitutions} {
     list [catch {subst {$long [set long] [bogus_command]}} msg] $msg
 } {1 {invalid command name "bogus_command"}}
+test subst-5.5 {command substitutions} {
+    set a 0
+    list [catch {subst {[set a 1}} msg] $a $msg 
+} {1 0 {missing close-bracket}}
+test subst-5.6 {command substitutions} {
+    set a 0
+    list [catch {subst {0[set a 1}} msg] $a $msg 
+} {1 0 {missing close-bracket}}
+test subst-5.7 {command substitutions} {
+    set a 0
+    list [catch {subst {0[set a 1; set a 2}} msg] $a $msg 
+} {1 1 {missing close-bracket}}
 
 test subst-6.1 {clear the result after command substitution} {
     catch {unset a}