From dd6aecfb4541cc4b0bad64cee7af6412ce88e8e8 Mon Sep 17 00:00:00 2001 From: avl Date: Wed, 1 Mar 2017 10:03:21 +0000 Subject: Implement (9): disallow $arr((() and ${{{} resulting in a consistent version of (4) --- generic/tclParse.c | 23 ++++++++++++++++++----- generic/tclParse.h | 2 ++ 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)] -- cgit v0.12