From 484de8b9879c4344a7f31bf0940aa2eaf943d30f Mon Sep 17 00:00:00 2001 From: dgp Date: Mon, 24 Nov 2014 03:00:03 +0000 Subject: [e087812465] Trim back operatorStrings array to just the entries that are needed. Trims away the part of the array that was out of sync with the opcodes. --- generic/tclExecute.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/generic/tclExecute.c b/generic/tclExecute.c index c4f9836..b9415e5 100644 --- a/generic/tclExecute.c +++ b/generic/tclExecute.c @@ -75,9 +75,7 @@ int tclTraceExec = 0; static const char *const operatorStrings[] = { "||", "&&", "|", "^", "&", "==", "!=", "<", ">", "<=", ">=", "<<", ">>", - "+", "-", "*", "/", "%", "+", "-", "~", "!", - "BUILTIN FUNCTION", "FUNCTION", - "", "", "", "", "", "", "", "", "eq", "ne" + "+", "-", "*", "/", "%", "+", "-", "~", "!" }; /* @@ -7714,7 +7712,7 @@ IllegalExprOperandType( if (opcode == INST_EXPON) { operator = "**"; - } else if (opcode <= INST_STR_NEQ) { + } else if (opcode <= INST_LNOT) { operator = operatorStrings[opcode - INST_LOR]; } -- cgit v0.12 From d9465a5be23e98e24bdbbc57ffee7b9459a565f8 Mon Sep 17 00:00:00 2001 From: dgp Date: Tue, 25 Nov 2014 21:24:06 +0000 Subject: One way to fix the parser of $-substitution accepting non-ASCII varnames. --- generic/tclParse.c | 3 +++ tests/parse.test | 3 +++ 2 files changed, 6 insertions(+) diff --git a/generic/tclParse.c b/generic/tclParse.c index e475fb8..1523eb3 100644 --- a/generic/tclParse.c +++ b/generic/tclParse.c @@ -1438,6 +1438,9 @@ Tcl_ParseVarName( offset = Tcl_UtfToUniChar(utfBytes, &ch); } c = UCHAR(ch); + if (c != ch) { + break; + } if (isalnum(c) || (c == '_')) { /* INTL: ISO only, UCHAR. */ src += offset; numBytes -= offset; diff --git a/tests/parse.test b/tests/parse.test index d7de5ff..cd02386 100644 --- a/tests/parse.test +++ b/tests/parse.test @@ -656,6 +656,9 @@ test parse-12.24 {Tcl_ParseVarName procedure, missing close paren in array refer test parse-12.25 {Tcl_ParseVarName procedure, nested array reference} testparser { testparser {$x(a$y(b$z))} 0 } {- {$x(a$y(b$z))} 1 word {$x(a$y(b$z))} 8 variable {$x(a$y(b$z))} 7 text x 0 text a 0 variable {$y(b$z)} 4 text y 0 text b 0 variable {$z} 1 text z 0 {}} +test parse-12.26 {Tcl_ParseVarName [d2ffcca163] non-ascii} testparser { + testparser "$\u0433" -1 +} "- {$\u0433} 1 word {$\u0433} 2 text {$} 0 text \u0433 0 {}" test parse-13.1 {Tcl_ParseVar procedure} testparsevar { set abc 24 -- cgit v0.12 From 92402afe21c8b0391c1727986781792eff7dbe86 Mon Sep 17 00:00:00 2001 From: dgp Date: Wed, 26 Nov 2014 16:22:40 +0000 Subject: I like this patch better. Retain the byte orientation of the parser. --- generic/tclParse.c | 21 ++++----------------- 1 file changed, 4 insertions(+), 17 deletions(-) diff --git a/generic/tclParse.c b/generic/tclParse.c index 1523eb3..90ec43d 100644 --- a/generic/tclParse.c +++ b/generic/tclParse.c @@ -1344,8 +1344,7 @@ Tcl_ParseVarName( Tcl_Token *tokenPtr; register const char *src; unsigned char c; - int varIndex, offset; - Tcl_UniChar ch; + int varIndex; unsigned array; if ((numBytes == 0) || (start == NULL)) { @@ -1428,22 +1427,10 @@ Tcl_ParseVarName( tokenPtr->numComponents = 0; while (numBytes) { - if (Tcl_UtfCharComplete(src, numBytes)) { - offset = Tcl_UtfToUniChar(src, &ch); - } else { - char utfBytes[TCL_UTF_MAX]; - - memcpy(utfBytes, src, (size_t) numBytes); - utfBytes[numBytes] = '\0'; - offset = Tcl_UtfToUniChar(utfBytes, &ch); - } - c = UCHAR(ch); - if (c != ch) { - break; - } + c = UCHAR(*src); if (isalnum(c) || (c == '_')) { /* INTL: ISO only, UCHAR. */ - src += offset; - numBytes -= offset; + src += 1; + numBytes -= 1; continue; } if ((c == ':') && (numBytes != 1) && (src[1] == ':')) { -- cgit v0.12 From 03f0d60f88e00392c71063d8617a35c685d2c474 Mon Sep 17 00:00:00 2001 From: dgp Date: Wed, 26 Nov 2014 17:00:55 +0000 Subject: Same issue in expr parser also tested and fixed. --- generic/tclCompExpr.c | 32 ++++++++++++-------------------- tests/parseExpr.test | 6 ++++++ 2 files changed, 18 insertions(+), 20 deletions(-) diff --git a/generic/tclCompExpr.c b/generic/tclCompExpr.c index 9142e2b..dde4e56 100644 --- a/generic/tclCompExpr.c +++ b/generic/tclCompExpr.c @@ -1969,31 +1969,23 @@ ParseLexeme( } } - if (Tcl_UtfCharComplete(start, numBytes)) { - scanned = Tcl_UtfToUniChar(start, &ch); - } else { - char utfBytes[TCL_UTF_MAX]; - memcpy(utfBytes, start, (size_t) numBytes); - utfBytes[numBytes] = '\0'; - scanned = Tcl_UtfToUniChar(utfBytes, &ch); - } - if (!isalnum(UCHAR(ch))) { - *lexemePtr = INVALID; - Tcl_DecrRefCount(literal); - return scanned; - } - end = start; - while (isalnum(UCHAR(ch)) || (UCHAR(ch) == '_')) { - end += scanned; - numBytes -= scanned; - if (Tcl_UtfCharComplete(end, numBytes)) { - scanned = Tcl_UtfToUniChar(end, &ch); + if (!isalnum(UCHAR(*start))) { + if (Tcl_UtfCharComplete(start, numBytes)) { + scanned = Tcl_UtfToUniChar(start, &ch); } else { char utfBytes[TCL_UTF_MAX]; - memcpy(utfBytes, end, (size_t) numBytes); + memcpy(utfBytes, start, (size_t) numBytes); utfBytes[numBytes] = '\0'; scanned = Tcl_UtfToUniChar(utfBytes, &ch); } + *lexemePtr = INVALID; + Tcl_DecrRefCount(literal); + return scanned; + } + end = start; + while (numBytes && (isalnum(UCHAR(*end)) || (UCHAR(*end) == '_'))) { + end += 1; + numBytes -= 1; } *lexemePtr = BAREWORD; if (literalPtr) { diff --git a/tests/parseExpr.test b/tests/parseExpr.test index c1c489b..3e0df29 100644 --- a/tests/parseExpr.test +++ b/tests/parseExpr.test @@ -1051,6 +1051,12 @@ test parseExpr-22.18 {Bug 3401704} -constraints testexprparser -body { testexprparser 0b02 -1 } -returnCodes error -match glob -result {*invalid binary number*} +test parseExpr-22.19 {Bug d2ffcca163} -constraints testexprparser -body { + testexprparser \u0433 -1 +} -returnCodes error -match glob -result {*invalid character*} +test parseExpr-22.20 {Bug d2ffcca163} -constraints testexprparser -body { + testexprparser \u043f -1 +} -returnCodes error -match glob -result {*invalid character*} # cleanup cleanupTests -- cgit v0.12 From d7cf041bab9ace3408763b9c55dcc337e53d4600 Mon Sep 17 00:00:00 2001 From: andreask Date: Mon, 1 Dec 2014 20:17:04 +0000 Subject: Fix missing export of the "NewForeachInfoType" AuxData structure for tbcload/tclcompiler packages. --- generic/tclCompile.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/generic/tclCompile.c b/generic/tclCompile.c index 3736498..0f4dfaf 100644 --- a/generic/tclCompile.c +++ b/generic/tclCompile.c @@ -4342,10 +4342,11 @@ TclInitAuxDataTypeTable(void) Tcl_InitHashTable(&auxDataTypeTable, TCL_STRING_KEYS); /* - * There are only three AuxData types at this time, so register them here. + * There are only four AuxData types at this time, so register them here. */ RegisterAuxDataType(&tclForeachInfoType); + RegisterAuxDataType(&tclNewForeachInfoType); RegisterAuxDataType(&tclJumptableInfoType); RegisterAuxDataType(&tclDictUpdateInfoType); } -- cgit v0.12 From 730a9a132cbd0a3b3ff36b842957b1cda50ed3a6 Mon Sep 17 00:00:00 2001 From: Miguel Sofer Date: Wed, 3 Dec 2014 13:22:53 +0000 Subject: adding a test for the bug --- tests/compile.test | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/tests/compile.test b/tests/compile.test index 22ebc7d..8150622 100644 --- a/tests/compile.test +++ b/tests/compile.test @@ -455,14 +455,22 @@ test compile-13.1 {testing underestimate of maxStackSize in list cmd} {exec} { list [catch {exec [interpreter] << $script} msg] $msg } {0 OK} -# Special test for compiling tokens from a copy of the source string. [Bug -# 599788] +# Tests compile-14.* for compiling tokens from a copy of the source string. +# [Bug 599788] [Bug 0c043a175a47da8c2342] test compile-14.1 {testing errors in element name; segfault?} {} { catch {set a([error])} msg1 catch {set bubba([join $abba $jubba]) $vol} msg2 list $msg1 $msg2 } {{wrong # args: should be "error message ?errorInfo? ?errorCode?"} {can't read "abba": no such variable}} +test compile-14.2 {testing element name "$"} -body { + unset a + set a() 1 + set a($) 2 + list [set a()] [set a($)] [unset a(); lindex [array names a] 0] +} -cleanup {unset a} -result {1 2 $} + + # Tests compile-15.* cover Tcl Bug 633204 test compile-15.1 {proper TCL_RETURN code from [return]} { apply {{} {catch return}} -- cgit v0.12 From 58cd08bb7d984dd94fd4b1203984f24d5b2c5484 Mon Sep 17 00:00:00 2001 From: dkf Date: Wed, 3 Dec 2014 23:05:15 +0000 Subject: [0dca3bfa8f] Strengthen validity checks on fast-path string comparison. --- generic/tclExecute.c | 8 +++++--- tests/stringComp.test | 8 ++++++++ 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/generic/tclExecute.c b/generic/tclExecute.c index 337a75f..b9da8fc 100644 --- a/generic/tclExecute.c +++ b/generic/tclExecute.c @@ -5410,8 +5410,8 @@ TEBCresume( s1 = (char *) Tcl_GetByteArrayFromObj(valuePtr, &s1len); s2 = (char *) Tcl_GetByteArrayFromObj(value2Ptr, &s2len); memCmpFn = memcmp; - } else if (((valuePtr->typePtr == &tclStringType) - && (value2Ptr->typePtr == &tclStringType))) { + } else if ((valuePtr->typePtr == &tclStringType) + && (value2Ptr->typePtr == &tclStringType)) { /* * Do a unicode-specific comparison if both of the args are of * String type. If the char length == byte length, we can do a @@ -5422,7 +5422,9 @@ TEBCresume( s1len = Tcl_GetCharLength(valuePtr); s2len = Tcl_GetCharLength(value2Ptr); if ((s1len == valuePtr->length) - && (s2len == value2Ptr->length)) { + && (valuePtr->bytes != NULL) + && (s2len == value2Ptr->length) + && (value2Ptr->bytes != NULL)) { s1 = valuePtr->bytes; s2 = value2Ptr->bytes; memCmpFn = memcmp; diff --git a/tests/stringComp.test b/tests/stringComp.test index f9f6bda..a66525e 100644 --- a/tests/stringComp.test +++ b/tests/stringComp.test @@ -720,6 +720,14 @@ test stringComp-14.2 {Bug 82e7f67325} memory { }} {a b} } } {0} +test stringComp-14.3 {Bug 0dca3bfa8f} { + apply {arg { + set argCopy $arg + set arg [string replace $arg 1 2 aa] + # Crashes in comparison before fix + expr {$arg ne $argCopy} + }} abcde +} 1 ## string tolower ## not yet bc -- cgit v0.12 From 8694763c10584bbaed0097318fcaa55a7b86425a Mon Sep 17 00:00:00 2001 From: Miguel Sofer Date: Wed, 3 Dec 2014 23:17:16 +0000 Subject: test and fix (thx dgp) --- generic/tclCompCmds.c | 2 +- tests/compile.test | 9 +++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/generic/tclCompCmds.c b/generic/tclCompCmds.c index 18f4564..4e7ef97 100644 --- a/generic/tclCompCmds.c +++ b/generic/tclCompCmds.c @@ -3373,7 +3373,7 @@ TclPushVarName( nameChars = p - varTokenPtr[1].start; elName = p + 1; remainingChars = (varTokenPtr[2].start - p) - 1; - elNameChars = (varTokenPtr[n].start-p) + varTokenPtr[n].size - 2; + elNameChars = (varTokenPtr[n].start-p) + varTokenPtr[n].size - 1; if (remainingChars) { /* diff --git a/tests/compile.test b/tests/compile.test index 8150622..45d69e9 100644 --- a/tests/compile.test +++ b/tests/compile.test @@ -464,11 +464,12 @@ test compile-14.1 {testing errors in element name; segfault?} {} { } {{wrong # args: should be "error message ?errorInfo? ?errorCode?"} {can't read "abba": no such variable}} test compile-14.2 {testing element name "$"} -body { - unset a + unset -nocomplain a set a() 1 - set a($) 2 - list [set a()] [set a($)] [unset a(); lindex [array names a] 0] -} -cleanup {unset a} -result {1 2 $} + set a(1) 2 + set a($) 3 + list [set a()] [set a(1)] [set a($)] [unset a(); lindex [array names a] 0] +} -cleanup {unset a} -result [list 1 2 3 {$}] # Tests compile-15.* cover Tcl Bug 633204 -- cgit v0.12 From 0c0be357100d28784d29e88ef2af8e61ffd7aeb1 Mon Sep 17 00:00:00 2001 From: Miguel Sofer Date: Wed, 3 Dec 2014 23:34:36 +0000 Subject: missing unset in new test --- tests/compile.test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/compile.test b/tests/compile.test index 45d69e9..7335293 100644 --- a/tests/compile.test +++ b/tests/compile.test @@ -468,7 +468,7 @@ test compile-14.2 {testing element name "$"} -body { set a() 1 set a(1) 2 set a($) 3 - list [set a()] [set a(1)] [set a($)] [unset a(); lindex [array names a] 0] + list [set a()] [set a(1)] [set a($)] [unset a() a(1); lindex [array names a] 0] } -cleanup {unset a} -result [list 1 2 3 {$}] -- cgit v0.12 From 7dfd9c5a9656fd1b66fcdc8111b3b49f7d3e1f8a Mon Sep 17 00:00:00 2001 From: dgp Date: Wed, 3 Dec 2014 23:54:16 +0000 Subject: Now make the patch by hand that fossil could not merge. --- tests/compile.test | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/compile.test b/tests/compile.test index 7335293..d4a31d4 100644 --- a/tests/compile.test +++ b/tests/compile.test @@ -455,8 +455,7 @@ test compile-13.1 {testing underestimate of maxStackSize in list cmd} {exec} { list [catch {exec [interpreter] << $script} msg] $msg } {0 OK} -# Tests compile-14.* for compiling tokens from a copy of the source string. -# [Bug 599788] [Bug 0c043a175a47da8c2342] +# Tests compile-14.* for [Bug 599788] [Bug 0c043a175a47da8c2342] test compile-14.1 {testing errors in element name; segfault?} {} { catch {set a([error])} msg1 catch {set bubba([join $abba $jubba]) $vol} msg2 -- cgit v0.12 From dd4c175c818027548fd867fe331db5239880b1fd Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 4 Dec 2014 18:26:31 +0000 Subject: Stop using isalnum(.). Its results are not portable. Replace with our own private routine TclIsBareword() that does exactly what we want. --- generic/tclCompExpr.c | 15 ++++++++++----- generic/tclInt.h | 1 + generic/tclParse.c | 47 +++++++++++++++++++++++++++++++++++++++++++---- 3 files changed, 54 insertions(+), 9 deletions(-) diff --git a/generic/tclCompExpr.c b/generic/tclCompExpr.c index dde4e56..2470931 100644 --- a/generic/tclCompExpr.c +++ b/generic/tclCompExpr.c @@ -1920,8 +1920,7 @@ ParseLexeme( literal = Tcl_NewObj(); if (TclParseNumber(NULL, literal, NULL, start, numBytes, &end, TCL_PARSE_NO_WHITESPACE) == TCL_OK) { - if (end < start + numBytes && !isalnum(UCHAR(*end)) - && UCHAR(*end) != '_') { + if (end < start + numBytes && !TclIsBareword(*end)) { number: TclInitStringRep(literal, start, end-start); @@ -1945,7 +1944,7 @@ ParseLexeme( if (literal->typePtr == &tclDoubleType) { const char *p = start; while (p < end) { - if (!isalnum(UCHAR(*p++))) { + if (!TclIsBareword(*p++)) { /* * The number has non-bareword characters, so we * must treat it as a number. @@ -1969,7 +1968,13 @@ ParseLexeme( } } - if (!isalnum(UCHAR(*start))) { + /* + * We reject leading underscores in bareword. No sensible reason why. + * Might be inspired by reserved identifier rules in C, which of course + * have no direct relevance here. + */ + + if (!TclIsBareword(*start) || *start == '_') { if (Tcl_UtfCharComplete(start, numBytes)) { scanned = Tcl_UtfToUniChar(start, &ch); } else { @@ -1983,7 +1988,7 @@ ParseLexeme( return scanned; } end = start; - while (numBytes && (isalnum(UCHAR(*end)) || (UCHAR(*end) == '_'))) { + while (numBytes && TclIsBareword(*end)) { end += 1; numBytes -= 1; } diff --git a/generic/tclInt.h b/generic/tclInt.h index dd66d76..255ee23 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -2608,6 +2608,7 @@ MODULE_SCOPE void TclInitSubsystems(void); MODULE_SCOPE int TclInterpReady(Tcl_Interp *interp); MODULE_SCOPE int TclIsLocalScalar(const char *src, int len); MODULE_SCOPE int TclIsSpaceProc(char byte); +MODULE_SCOPE int TclIsBareword(char byte); MODULE_SCOPE int TclJoinThread(Tcl_ThreadId id, int *result); MODULE_SCOPE void TclLimitRemoveAllHandlers(Tcl_Interp *interp); MODULE_SCOPE Tcl_Obj * TclLindexList(Tcl_Interp *interp, diff --git a/generic/tclParse.c b/generic/tclParse.c index 90ec43d..025304c 100644 --- a/generic/tclParse.c +++ b/generic/tclParse.c @@ -628,6 +628,47 @@ TclIsSpaceProc( /* *---------------------------------------------------------------------- * + * TclIsBareword-- + * + * Report whether byte is one that can be part of a "bareword". + * This concept is named in expression parsing, where it determines + * what can be a legal function name, but is the same definition used + * in determining what variable names can be parsed as variable + * substitutions without the benefit of enclosing braces. The set of + * ASCII chars that are accepted are the numeric chars ('0'-'9'), + * the alphabetic chars ('a'-'z', 'A'-'Z') and underscore ('_'). + * + * Results: + * Returns 1, if byte is in the accepted set of chars, 0 otherwise. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +int +TclIsBareword( + char byte) +{ + if (byte < '0' || byte > 'z') { + return 0; + } + if (byte <= '9' || byte >= 'a') { + return 1; + } + if (byte == '_') { + return 1; + } + if (byte < 'A' || byte > 'Z') { + return 0; + } + return 1; +} + +/* + *---------------------------------------------------------------------- + * * ParseWhiteSpace -- * * Scans up to numBytes bytes starting at src, consuming white space @@ -1343,7 +1384,6 @@ Tcl_ParseVarName( { Tcl_Token *tokenPtr; register const char *src; - unsigned char c; int varIndex; unsigned array; @@ -1427,13 +1467,12 @@ Tcl_ParseVarName( tokenPtr->numComponents = 0; while (numBytes) { - c = UCHAR(*src); - if (isalnum(c) || (c == '_')) { /* INTL: ISO only, UCHAR. */ + if (TclIsBareword(*src)) { src += 1; numBytes -= 1; continue; } - if ((c == ':') && (numBytes != 1) && (src[1] == ':')) { + if ((src[0] == ':') && (numBytes != 1) && (src[1] == ':')) { src += 2; numBytes -= 2; while (numBytes && (*src == ':')) { -- cgit v0.12 From 6d936db4a3aa4bed9449e2810de3dd9b20ecc6b2 Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 4 Dec 2014 20:45:11 +0000 Subject: The isalpha(.) calls remaining in the expr parser still bring nonportability. Commit a test that demonstrates that. --- tests/parseExpr.test | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/parseExpr.test b/tests/parseExpr.test index 3e0df29..c3b0d71 100644 --- a/tests/parseExpr.test +++ b/tests/parseExpr.test @@ -1057,6 +1057,9 @@ test parseExpr-22.19 {Bug d2ffcca163} -constraints testexprparser -body { test parseExpr-22.20 {Bug d2ffcca163} -constraints testexprparser -body { testexprparser \u043f -1 } -returnCodes error -match glob -result {*invalid character*} +test parseExpr-22.21 {Bug d2ffcca163} -constraints testexprparser -body { + testexprparser in\u0433(0) -1 +} -returnCodes error -match glob -result {missing operand*} # cleanup cleanupTests -- cgit v0.12 From 5c1b9fefdfb50cee5cd7d053101a033b2b6bb0d3 Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 4 Dec 2014 21:29:18 +0000 Subject: Limit isalpha(.) calls in the expr parser to only apply to known ASCII arguments to make the results portable. --- generic/tclCompExpr.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/generic/tclCompExpr.c b/generic/tclCompExpr.c index 2470931..7b67970 100644 --- a/generic/tclCompExpr.c +++ b/generic/tclCompExpr.c @@ -1883,7 +1883,7 @@ ParseLexeme( case 'i': if ((numBytes > 1) && (start[1] == 'n') - && ((numBytes == 2) || !isalpha(UCHAR(start[2])))) { + && ((numBytes == 2) || start[2] & 0x80 || !isalpha(start[2]))) { /* * Must make this check so we can tell the difference between @@ -1898,14 +1898,15 @@ ParseLexeme( case 'e': if ((numBytes > 1) && (start[1] == 'q') - && ((numBytes == 2) || !isalpha(UCHAR(start[2])))) { + && ((numBytes == 2) || start[2] & 0x80 || !isalpha(start[2]))) { *lexemePtr = STREQ; return 2; } break; case 'n': - if ((numBytes > 1) && ((numBytes == 2) || !isalpha(UCHAR(start[2])))) { + if ((numBytes > 1) + && ((numBytes == 2) || start[2] & 0x80 || !isalpha(start[2]))) { switch (start[1]) { case 'e': *lexemePtr = STRNEQ; -- cgit v0.12 From b52476a5cdc6924d597f7bc9dbd89f0717058009 Mon Sep 17 00:00:00 2001 From: dgp Date: Fri, 5 Dec 2014 21:05:17 +0000 Subject: Ever since (Tcl)PushVarName() stopped making a recursive call to Tcl_ParseCommand() (in the pre-8.4.0 timeframe), there's been no need for special protections for brace-quoted varname words. A simple word is a simple word is a simple word. --- generic/tclCompCmds.c | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/generic/tclCompCmds.c b/generic/tclCompCmds.c index 2f72263..c8ca828 100644 --- a/generic/tclCompCmds.c +++ b/generic/tclCompCmds.c @@ -4890,16 +4890,7 @@ PushVarName( nameChars = elNameChars = 0; localIndex = -1; - /* - * Check not only that the type is TCL_TOKEN_SIMPLE_WORD, but whether - * curly braces surround the variable name. This really matters for array - * elements to handle things like - * set {x($foo)} 5 - * which raises an undefined var error if we are not careful here. - */ - - if ((varTokenPtr->type == TCL_TOKEN_SIMPLE_WORD) && - (varTokenPtr->start[0] != '{')) { + if (varTokenPtr->type == TCL_TOKEN_SIMPLE_WORD) { /* * A simple variable name. Divide it up into "name" and "elName" * strings. If it is not a local variable, look it up at runtime. -- cgit v0.12 From 58bde2cb77be95dfc210c6b7448b9c82cf140025 Mon Sep 17 00:00:00 2001 From: ashok Date: Sat, 6 Dec 2014 11:19:32 +0000 Subject: Potential fix for [c6ed4acfd8]. Simple typo in original fix for [336441ed59]. Was looping on statePtr->next instead of statePtr2->next. Would result in an infinite loop. Definitely a bug but whether it completely fixes the above in all cases needs to be tested. --- win/tclWinSock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/win/tclWinSock.c b/win/tclWinSock.c index 2c58224..f5658ba 100644 --- a/win/tclWinSock.c +++ b/win/tclWinSock.c @@ -1739,7 +1739,7 @@ TcpConnect( */ for (statePtr2 = tsdPtr->socketList; statePtr2 != NULL; - statePtr2 = statePtr->nextPtr) { + statePtr2 = statePtr2->nextPtr) { if (statePtr2 == statePtr) { in_socket_list = 1; break; -- cgit v0.12 From 7466351c908df509ab68c9cd3fdafa793bebfc75 Mon Sep 17 00:00:00 2001 From: oehhar Date: Sun, 7 Dec 2014 12:17:24 +0000 Subject: test for bug [c6ed4acfd8]: running async socket connect with other connect established will block tcl as it goes in an infinite loop in vwait --- tests/socket.test | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/tests/socket.test b/tests/socket.test index eeea044..4f90e51 100644 --- a/tests/socket.test +++ b/tests/socket.test @@ -2343,6 +2343,24 @@ test socket-14.17 {empty -sockname while [socket -async] connecting} \ catch {close $client} } -result {} +# test for bug c6ed4acfd8: running async socket connect with other connect +# established will block tcl as it goes in an infinite loop in vwait +test socket-14.18 {bug c6ed4acfd8: running async socket connect made other connect block} \ + -constraints {socket} \ + -body { + proc accept {channel address port} {} + set port [randport] + set ssock [socket -server accept $port] + set csock1 [socket -async localhost [randport]] + set csock2 [socket localhost $port] + after 1000 {set done ok} + vwait done +} -cleanup { + catch {close $ssock} + catch {close $csock1} + catch {close $csock2} + } -result {} + set num 0 set x {localhost {socket} 127.0.0.1 {supported_inet} ::1 {supported_inet6}} -- cgit v0.12 From b27238fbbb6ee992d3f908e53606d862a8100c46 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Mon, 8 Dec 2014 16:05:19 +0000 Subject: Fix some gcc compiler warnings (probably cygwin-only) --- generic/tclCompExpr.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/generic/tclCompExpr.c b/generic/tclCompExpr.c index 7b67970..23dc0a4 100644 --- a/generic/tclCompExpr.c +++ b/generic/tclCompExpr.c @@ -1883,7 +1883,7 @@ ParseLexeme( case 'i': if ((numBytes > 1) && (start[1] == 'n') - && ((numBytes == 2) || start[2] & 0x80 || !isalpha(start[2]))) { + && ((numBytes == 2) || start[2] & 0x80 || !isalpha(UCHAR(start[2])))) { /* * Must make this check so we can tell the difference between @@ -1898,7 +1898,7 @@ ParseLexeme( case 'e': if ((numBytes > 1) && (start[1] == 'q') - && ((numBytes == 2) || start[2] & 0x80 || !isalpha(start[2]))) { + && ((numBytes == 2) || start[2] & 0x80 || !isalpha(UCHAR(start[2])))) { *lexemePtr = STREQ; return 2; } @@ -1906,7 +1906,7 @@ ParseLexeme( case 'n': if ((numBytes > 1) - && ((numBytes == 2) || start[2] & 0x80 || !isalpha(start[2]))) { + && ((numBytes == 2) || start[2] & 0x80 || !isalpha(UCHAR(start[2])))) { switch (start[1]) { case 'e': *lexemePtr = STRNEQ; -- cgit v0.12