summaryrefslogtreecommitdiffstats
path: root/generic/tclParse.c
diff options
context:
space:
mode:
authorferrieux <ferrieux@users.sourceforge.net>2008-11-17 22:26:53 (GMT)
committerferrieux <ferrieux@users.sourceforge.net>2008-11-17 22:26:53 (GMT)
commitdee5b7a791b4b64cdfe7ae6c9981aff8d85848d5 (patch)
tree2feeafa4d0aa3b3a07938ff5db6643a4ee5dc488 /generic/tclParse.c
parentdb2e6bf825388498ab5798bbeca26fce23d4286f (diff)
downloadtcl-dee5b7a791b4b64cdfe7ae6c9981aff8d85848d5.zip
tcl-dee5b7a791b4b64cdfe7ae6c9981aff8d85848d5.tar.gz
tcl-dee5b7a791b4b64cdfe7ae6c9981aff8d85848d5.tar.bz2
Fix [Bug 2251175]: missing backslash substitution on expanded literals.
Diffstat (limited to 'generic/tclParse.c')
-rw-r--r--generic/tclParse.c39
1 files changed, 36 insertions, 3 deletions
diff --git a/generic/tclParse.c b/generic/tclParse.c
index c730eaa..e1278a0 100644
--- a/generic/tclParse.c
+++ b/generic/tclParse.c
@@ -12,7 +12,7 @@
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclParse.c,v 1.73 2008/10/26 18:34:04 dkf Exp $
+ * RCS: @(#) $Id: tclParse.c,v 1.74 2008/11/17 22:26:54 ferrieux Exp $
*/
#include "tclInt.h"
@@ -532,6 +532,28 @@ Tcl_ParseCommand(
tokenPtr[-1].size += (isspace(UCHAR(
tokenPtr->start[tokenPtr->size])) == 0);
}
+ if (tokenPtr[-1].start[0]!='{')
+ {
+ const char *s;
+ int n;
+
+ for(n=tokenPtr->size,s=tokenPtr->start;n>0;n--,s++)
+ {
+ if ((*s)=='\\') {
+ tokenPtr->type = TCL_TOKEN_UNCOLLAPSED_TEXT;
+ /*
+ * In this case we also demote the
+ * enclosing token from
+ * SIMPLE_WORD to WORD in order to
+ * preserve the simplicity of all
+ * shortcuts made on SIMPLE_WORDs
+ * in clients.
+ */
+ tokenPtr[-1].type = TCL_TOKEN_WORD;
+ break;
+ }
+ }
+ }
tokenPtr++;
}
@@ -546,7 +568,7 @@ Tcl_ParseCommand(
tokenPtr->type = TCL_TOKEN_EXPAND_WORD;
}
} else if ((tokenPtr->numComponents == 1)
- && (tokenPtr[1].type == TCL_TOKEN_TEXT)) {
+ && (tokenPtr[1].type & (TCL_TOKEN_TEXT|TCL_TOKEN_UNCOLLAPSED_TEXT))) {
tokenPtr->type = TCL_TOKEN_SIMPLE_WORD;
}
@@ -1961,7 +1983,7 @@ Tcl_SubstObj(
if (varTokenPtr->type != TCL_TOKEN_VARIABLE) {
Tcl_Panic("Tcl_SubstObj: programming error");
}
- if (varTokenPtr[1].type != TCL_TOKEN_TEXT) {
+ if (!(varTokenPtr[1].type & (TCL_TOKEN_TEXT|TCL_TOKEN_UNCOLLAPSED_TEXT))) {
Tcl_Panic("Tcl_SubstObj: programming error");
}
parsePtr->numTokens -= 2;
@@ -2134,6 +2156,7 @@ TclSubstTokens(
{
Tcl_Obj *result;
int code = TCL_OK;
+ char *collapsed = NULL;
/*
* Each pass through this loop will substitute one token, and its
@@ -2158,6 +2181,15 @@ TclSubstTokens(
appendByteLength = tokenPtr->size;
break;
+ case TCL_TOKEN_UNCOLLAPSED_TEXT:
+ if (collapsed)
+ collapsed=ckrealloc(collapsed,tokenPtr->size);
+ else
+ collapsed=ckalloc(tokenPtr->size);
+ appendByteLength=TclCopyAndCollapse(tokenPtr->size,tokenPtr->start,collapsed);
+ append=collapsed;
+ break;
+
case TCL_TOKEN_BS:
appendByteLength = Tcl_UtfBackslash(tokenPtr->start, NULL,
utfCharBytes);
@@ -2270,6 +2302,7 @@ TclSubstTokens(
}
}
}
+ if (collapsed) ckfree(collapsed);
if (code != TCL_ERROR) { /* Keep error message in result! */
if (result != NULL) {