From 7cb8eb7218804199155464c4441c47b8a2fbf677 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Tue, 25 Aug 2020 16:09:04 +0000 Subject: Add test-case util-9.59, which demonstrates bug [b5777d3d32] --- tests/util.test | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/util.test b/tests/util.test index b516a0e..03fa9fe 100644 --- a/tests/util.test +++ b/tests/util.test @@ -818,6 +818,9 @@ test util-9.57 {Tcl_GetIntForIndex} { test util-9.58 {Tcl_GetIntForIndex} -body { string index abcd end--0x8000000000000000 } -result {} +test util-9.59 {Tcl_GetIntForIndex} { + string index abcd 0-0x10000000000000000 +} {} test util-10.1 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} { convertDouble 0x0000000000000000 -- cgit v0.12 From de2793025fcbb875f0ac1e7efed956bbfedca273 Mon Sep 17 00:00:00 2001 From: dgp Date: Wed, 2 Sep 2020 16:20:20 +0000 Subject: Different fix where existing protection tools for nesting bytecode execution calls are used. This solution suggests there may be many more places needing protection. Any routine that gets passed "interp" is a possibility. --- generic/tclExecute.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/generic/tclExecute.c b/generic/tclExecute.c index 0f1c2cc..70ed54a 100644 --- a/generic/tclExecute.c +++ b/generic/tclExecute.c @@ -5298,10 +5298,13 @@ TEBCresume( */ length = Tcl_GetCharLength(valuePtr); + DECACHE_STACK_INFO(); if (TclGetIntForIndexM(interp, value2Ptr, length-1, &index)!=TCL_OK) { + CACHE_STACK_INFO(); TRACE_ERROR(interp); goto gotError; } + CACHE_STACK_INFO(); if ((index < 0) || (index >= length)) { TclNewObj(objResultPtr); -- cgit v0.12 From ee7073e46860e7e4746d0f8d68a8b66e708eb763 Mon Sep 17 00:00:00 2001 From: dgp Date: Wed, 2 Sep 2020 19:50:32 +0000 Subject: Test lindex-18.0 demonstrates same issue with INST_LIST_INDEX --- tests/lindex.test | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/lindex.test b/tests/lindex.test index 41c803b..fa5c996 100644 --- a/tests/lindex.test +++ b/tests/lindex.test @@ -449,6 +449,14 @@ test lindex-17.1 {Bug 1718580} -body { lindex a end foo } -match glob -result {bad index "foo"*} -returnCodes 1 +test lindex-18.0 {nested bytecode execution} -setup { + proc demo {i} {lindex {a b c} $i} +} -body { + demo 0+0x10000000000000000 +} -cleanup { + rename demo {} +} + catch { unset minus } # cleanup -- cgit v0.12 From 712f88bef73db43ea3e8169d8c5609ec420b3bf2 Mon Sep 17 00:00:00 2001 From: dgp Date: Wed, 2 Sep 2020 20:22:15 +0000 Subject: Fix for test lindex-18.0 --- generic/tclExecute.c | 20 +++++++++++++------- generic/tclUtil.c | 17 ++++++++--------- 2 files changed, 21 insertions(+), 16 deletions(-) diff --git a/generic/tclExecute.c b/generic/tclExecute.c index 70ed54a..890ce08 100644 --- a/generic/tclExecute.c +++ b/generic/tclExecute.c @@ -4857,13 +4857,19 @@ TEBCresume( */ if ((TclListObjGetElements(interp, valuePtr, &objc, &objv) == TCL_OK) - && !TclHasIntRep(value2Ptr, &tclListType) - && (TclGetIntForIndexM(NULL, value2Ptr, objc-1, - &index) == TCL_OK)) { - TclDecrRefCount(value2Ptr); - tosPtr--; - pcAdjustment = 1; - goto lindexFastPath; + && !TclHasIntRep(value2Ptr, &tclListType)) { + int code; + + DECACHE_STACK_INFO(); + code = TclGetIntForIndexM(interp, value2Ptr, objc-1, &index); + CACHE_STACK_INFO(); + if (code == TCL_OK) { + TclDecrRefCount(value2Ptr); + tosPtr--; + pcAdjustment = 1; + goto lindexFastPath; + } + Tcl_ResetResult(interp); } objResultPtr = TclLindexList(interp, valuePtr, value2Ptr); diff --git a/generic/tclUtil.c b/generic/tclUtil.c index 5b296f0..8db6606 100644 --- a/generic/tclUtil.c +++ b/generic/tclUtil.c @@ -3817,7 +3817,7 @@ GetEndOffsetFromObj( if ((t1 == TCL_NUMBER_INT) && (t2 == TCL_NUMBER_INT)) { /* Both are wide, do wide-integer math */ if (*opPtr == '-') { - if ((w2 == WIDE_MIN) && (interp != NULL)) { + if (w2 == WIDE_MIN) { goto extreme; } w2 = -w2; @@ -3839,13 +3839,6 @@ GetEndOffsetFromObj( offset = WIDE_MIN; } } - } else if (interp == NULL) { - /* - * We use an interp to do bignum index calculations. - * If we don't get one, call all indices with bignums errors, - * and rely on callers to handle it. - */ - goto parseError; } else { /* * At least one is big, do bignum math. Little reason to @@ -3856,7 +3849,13 @@ GetEndOffsetFromObj( Tcl_Obj *sum; extreme: - Tcl_ExprObj(interp, objPtr, &sum); + if (interp) { + Tcl_ExprObj(interp, objPtr, &sum); + } else { + Tcl_Interp *compute = Tcl_CreateInterp(); + Tcl_ExprObj(compute, objPtr, &sum); + Tcl_DeleteInterp(compute); + } TclGetNumberFromObj(NULL, sum, &cd, &numType); if (numType == TCL_NUMBER_INT) { -- cgit v0.12 From 9f309d56cc2544def77f3c913d28aa1c1f8e2e14 Mon Sep 17 00:00:00 2001 From: dgp Date: Wed, 2 Sep 2020 20:50:43 +0000 Subject: Tests string-12.2[45].* and fixes to INST_STRING_RANGE. --- generic/tclExecute.c | 12 ++++++++++-- tests/string.test | 14 ++++++++++++++ 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/generic/tclExecute.c b/generic/tclExecute.c index 890ce08..3d39e89 100644 --- a/generic/tclExecute.c +++ b/generic/tclExecute.c @@ -5347,13 +5347,21 @@ TEBCresume( TRACE(("\"%.20s\" %.20s %.20s =>", O2S(OBJ_AT_DEPTH(2)), O2S(OBJ_UNDER_TOS), O2S(OBJ_AT_TOS))); length = Tcl_GetCharLength(OBJ_AT_DEPTH(2)) - 1; + + DECACHE_STACK_INFO(); if (TclGetIntForIndexM(interp, OBJ_UNDER_TOS, length, - &fromIdx) != TCL_OK - || TclGetIntForIndexM(interp, OBJ_AT_TOS, length, + &fromIdx) != TCL_OK) { + CACHE_STACK_INFO(); + TRACE_ERROR(interp); + goto gotError; + } + if (TclGetIntForIndexM(interp, OBJ_AT_TOS, length, &toIdx) != TCL_OK) { + CACHE_STACK_INFO(); TRACE_ERROR(interp); goto gotError; } + CACHE_STACK_INFO(); if (fromIdx < 0) { fromIdx = 0; diff --git a/tests/string.test b/tests/string.test index e42da8e..ba0780a 100644 --- a/tests/string.test +++ b/tests/string.test @@ -1506,6 +1506,20 @@ test string-12.22.$noComp {string range, shimmering binary/index} { test string-12.23.$noComp {string range, surrogates, bug [11ae2be95dac9417]} utf16 { run {list [string range a\U100000b 1 1] [string range a\U100000b 2 2] [string range a\U100000b 3 3]} } [list \U100000 {} b] +test string-12.24.$noComp {bignum index arithmetic} -setup { + proc demo {i j} {string range fubar $i $j} +} -cleanup { + rename demo {} +} -body { + demo 2 0+0x10000000000000000 +} -result bar +test string-12.25.$noComp {bignum index arithmetic} -setup { + proc demo {i j} {string range fubar $i $j} +} -cleanup { + rename demo {} +} -body { + demo 0x10000000000000000-0xffffffffffffffff 3 +} -result uba test string-13.1.$noComp {string repeat} { list [catch {run {string repeat}} msg] $msg -- cgit v0.12 From db325590a751eae6a25ee6ba9f749ba499ff2078 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Fri, 4 Sep 2020 06:04:47 +0000 Subject: Protect INST_STR_REPLACE too --- generic/tclExecute.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/generic/tclExecute.c b/generic/tclExecute.c index 3d39e89..6c631e2 100644 --- a/generic/tclExecute.c +++ b/generic/tclExecute.c @@ -5444,14 +5444,17 @@ TEBCresume( endIdx = Tcl_GetCharLength(valuePtr) - 1; TRACE(("\"%.20s\" %s %s \"%.20s\" => ", O2S(valuePtr), O2S(OBJ_UNDER_TOS), O2S(OBJ_AT_TOS), O2S(value3Ptr))); + DECACHE_STACK_INFO(); if (TclGetIntForIndexM(interp, OBJ_UNDER_TOS, endIdx, &fromIdx) != TCL_OK || TclGetIntForIndexM(interp, OBJ_AT_TOS, endIdx, &toIdx) != TCL_OK) { + CACHE_STACK_INFO(); TclDecrRefCount(value3Ptr); TRACE_ERROR(interp); goto gotError; } + CACHE_STACK_INFO(); TclDecrRefCount(OBJ_AT_TOS); (void) POP_OBJECT(); TclDecrRefCount(OBJ_AT_TOS); -- cgit v0.12