summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoravl <avl>2017-03-01 10:03:21 (GMT)
committeravl <avl>2017-03-01 10:03:21 (GMT)
commitdd6aecfb4541cc4b0bad64cee7af6412ce88e8e8 (patch)
tree8a206bf91b09e52ef1fd7fb6f8bdaef328a60ecd
parentc4b543db2553b963df18edea726276e1ca8a93e2 (diff)
downloadtcl-dd6aecfb4541cc4b0bad64cee7af6412ce88e8e8.zip
tcl-dd6aecfb4541cc4b0bad64cee7af6412ce88e8e8.tar.gz
tcl-dd6aecfb4541cc4b0bad64cee7af6412ce88e8e8.tar.bz2
Implement (9): disallow $arr((() and ${{{} resulting in a consistent version of (4)
-rw-r--r--generic/tclParse.c23
-rw-r--r--generic/tclParse.h2
2 files changed, 20 insertions, 5 deletions
diff --git a/generic/tclParse.c b/generic/tclParse.c
index 252d5e3..425b43f 100644
--- a/generic/tclParse.c
+++ b/generic/tclParse.c
@@ -95,7 +95,7 @@ const char tclCharTypeTable[] = {
TYPE_NORMAL, TYPE_NORMAL, TYPE_NORMAL, TYPE_NORMAL,
TYPE_SPACE, TYPE_NORMAL, TYPE_QUOTE, TYPE_NORMAL,
TYPE_SUBS, TYPE_NORMAL, TYPE_NORMAL, TYPE_NORMAL,
- TYPE_NORMAL, TYPE_CLOSE_PAREN, TYPE_NORMAL, TYPE_NORMAL,
+ TYPE_OPEN_PAREN, TYPE_CLOSE_PAREN, TYPE_NORMAL, TYPE_NORMAL,
TYPE_NORMAL, TYPE_NORMAL, TYPE_NORMAL, TYPE_NORMAL,
TYPE_NORMAL, TYPE_NORMAL, TYPE_NORMAL, TYPE_NORMAL,
TYPE_NORMAL, TYPE_NORMAL, TYPE_NORMAL, TYPE_NORMAL,
@@ -1364,7 +1364,7 @@ Tcl_ParseVarName(
{
Tcl_Token *tokenPtr;
register const char *src;
- int varIndex;
+ int varIndex, braceCount = 0;
unsigned array;
if ((numBytes == 0) || (start == NULL)) {
@@ -1417,15 +1417,20 @@ Tcl_ParseVarName(
*/
if (*src == '{') {
+ char ch;
src++;
numBytes--;
tokenPtr->type = TCL_TOKEN_TEXT;
tokenPtr->start = src;
tokenPtr->numComponents = 0;
- while (numBytes && (*src != '}')) {
+ ch = *src;
+ while (numBytes && (braceCount>0 || ch != '}')) {
+ if (ch == '{') { braceCount++; }
+ else if (ch == '}') { braceCount--; }
numBytes--;
src++;
+ ch= *src;
}
if (numBytes == 0) {
if (parsePtr->interp != NULL) {
@@ -1481,11 +1486,11 @@ Tcl_ParseVarName(
* any number of substitutions.
*/
- if (TCL_OK != TclParseTokens(src+1, numBytes-1, TYPE_CLOSE_PAREN,
+ if (TCL_OK != TclParseTokens(src+1, numBytes-1, TYPE_BAD_ARRAY_INDEX,
TCL_SUBST_ALL, parsePtr)) {
goto error;
}
- if ((parsePtr->term == src+numBytes) || (*parsePtr->term != ')')){
+ if ((parsePtr->term == src+numBytes)){
if (parsePtr->interp != NULL) {
Tcl_SetObjResult(parsePtr->interp, Tcl_NewStringObj(
"missing )", -1));
@@ -1494,6 +1499,14 @@ Tcl_ParseVarName(
parsePtr->term = src;
parsePtr->incomplete = 1;
goto error;
+ } else if ((*parsePtr->term != ')')){
+ if (parsePtr->interp != NULL) {
+ Tcl_SetObjResult(parsePtr->interp, Tcl_NewStringObj(
+ "invalid char in array index", -1));
+ }
+ parsePtr->errorType = TCL_PARSE_SYNTAX;
+ parsePtr->term = src;
+ goto error;
}
src = parsePtr->term + 1;
}
diff --git a/generic/tclParse.h b/generic/tclParse.h
index 20c609c..a836147 100644
--- a/generic/tclParse.h
+++ b/generic/tclParse.h
@@ -11,6 +11,8 @@
#define TYPE_CLOSE_PAREN 0x10
#define TYPE_CLOSE_BRACK 0x20
#define TYPE_BRACE 0x40
+#define TYPE_OPEN_PAREN 0x80
+#define TYPE_BAD_ARRAY_INDEX (TYPE_OPEN_PAREN|TYPE_CLOSE_PAREN|TYPE_QUOTE|TYPE_BRACE)
#define CHAR_TYPE(c) (tclCharTypeTable+128)[(int)(c)]