From 2c28b11277b488c5a421ebc815cf60e23299b38e Mon Sep 17 00:00:00 2001 From: sebres Date: Mon, 12 Aug 2024 13:06:21 +0000 Subject: incr.test: added coverage for bug [7179c6724cd38271] (broken compile of incr by wide2int overflow of immutable constant) --- tests/incr.test | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 57 insertions(+), 1 deletion(-) diff --git a/tests/incr.test b/tests/incr.test index 253cb1d..ae70fa2 100644 --- a/tests/incr.test +++ b/tests/incr.test @@ -236,7 +236,63 @@ test incr-1.30 {TclCompileIncrCmd: array var, braced (no subs)} { set array(\$foo) 4 incr {array($foo)} } 5 - + +test incr-1.31 {no overflow in TclCompileIncrCmd and Tcl_IncrObjCmd, bug [7179c6724cd38271]} { + # TclCompileIncrCmd: compiled incr TEBC with immutable constant offs (INST_INCR_*_IMM instructions): + lappend res [set i 0; incr i 0x7FFFFFFF] + lappend res [set i 0; incr i 0xFFFFFF80] + lappend res [set i 0; incr i 0xFFFFFF81] + lappend res [set i 0; incr i 0xFFFFFFFF] + lappend res [set i 0; incr i 0x10000007F] + lappend res [set i 0; incr i 0x100000080] + lappend res [set i 0; incr i 0x7FFFFFFFFFFFFFFF] + lappend res [set i 0; incr i 0xFFFFFFFFFFFFFF80] + lappend res [set i 0; incr i 0xFFFFFFFFFFFFFF81] + lappend res [set i 0; incr i 0xFFFFFFFFFFFFFFFF] + lappend res [set i 0; incr i 0x1000000000000007F] + lappend res [set i 0; incr i 0x10000000000000080] + # TclCompileIncrCmd: compiled incr TEBC with dynamic offs (INST_INCR_* instructions without _IMM): + lappend res [set i 0; incr i [set x 0x7FFFFFFF]] + lappend res [set i 0; incr i [set x 0xFFFFFF80]] + lappend res [set i 0; incr i [set x 0xFFFFFF81]] + lappend res [set i 0; incr i [set x 0xFFFFFFFF]] + lappend res [set i 0; incr i [set x 0x10000007F]] + lappend res [set i 0; incr i [set x 0x100000080]] + lappend res [set i 0; incr i [set x 0x7FFFFFFFFFFFFFFF]] + lappend res [set i 0; incr i [set x 0xFFFFFFFFFFFFFF80]] + lappend res [set i 0; incr i [set x 0xFFFFFFFFFFFFFF81]] + lappend res [set i 0; incr i [set x 0xFFFFFFFFFFFFFFFF]] + lappend res [set i 0; incr i [set x 0x1000000000000007F]] + lappend res [set i 0; incr i [set x 0x10000000000000080]] + # Tcl_IncrObjCmd: non-compiled incr command (or NRE): + set cmd incr + lappend res [set i 0; $cmd i 0x7FFFFFFF] + lappend res [set i 0; $cmd i 0xFFFFFF80] + lappend res [set i 0; $cmd i 0xFFFFFF81] + lappend res [set i 0; $cmd i 0xFFFFFFFF] + lappend res [set i 0; $cmd i 0x10000007F] + lappend res [set i 0; $cmd i 0x100000080] + lappend res [set i 0; $cmd i 0x7FFFFFFFFFFFFFFF] + lappend res [set i 0; $cmd i 0xFFFFFFFFFFFFFF80] + lappend res [set i 0; $cmd i 0xFFFFFFFFFFFFFF81] + lappend res [set i 0; $cmd i 0xFFFFFFFFFFFFFFFF] + lappend res [set i 0; $cmd i 0x1000000000000007F] + lappend res [set i 0; $cmd i 0x10000000000000080] +} [lrepeat 3 \ + [expr 0x7FFFFFFF] \ + [expr 0xFFFFFF80] \ + [expr 0xFFFFFF81] \ + [expr 0xFFFFFFFF] \ + [expr 0x10000007F] \ + [expr 0x100000080] \ + [expr 0x7FFFFFFFFFFFFFFF] \ + [expr 0xFFFFFFFFFFFFFF80] \ + [expr 0xFFFFFFFFFFFFFF81] \ + [expr 0xFFFFFFFFFFFFFFFF] \ + [expr 0x1000000000000007F] \ + [expr 0x10000000000000080] \ +] + # Check "incr" and computed command names. test incr-2.0 {incr and computed command names} { -- cgit v0.12 From 7c603bb3f40a4c0f2903eecb0ea92d9bfec5eb55 Mon Sep 17 00:00:00 2001 From: sebres Date: Mon, 12 Aug 2024 13:07:24 +0000 Subject: fixes [7179c6724cd38271]: compilation of incr command on wide constant offset (no overflow) --- generic/tclCompCmds.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/generic/tclCompCmds.c b/generic/tclCompCmds.c index 3b234b0..5f2dc43 100644 --- a/generic/tclCompCmds.c +++ b/generic/tclCompCmds.c @@ -2285,10 +2285,19 @@ TclCompileIncrCmd( Tcl_Obj *intObj = Tcl_NewStringObj(word, numBytes); Tcl_IncrRefCount(intObj); code = TclGetIntFromObj(NULL, intObj, &immValue); - TclDecrRefCount(intObj); - if ((code == TCL_OK) && (-127 <= immValue) && (immValue <= 127)) { + if ( (code == TCL_OK) + && (-127 <= immValue) && (immValue <= 127) +#ifndef NO_WIDE_TYPE + /* avoid overflow during string to int conversion (wide 0xFFFFFFFF to signed int -1): */ + && ( (immValue >= 0) + || (intObj->typePtr != &tclWideIntType) + || ((-127 <= intObj->internalRep.wideValue) && (intObj->internalRep.wideValue <= 127)) + ) +#endif + ) { haveImmValue = 1; } + TclDecrRefCount(intObj); if (!haveImmValue) { PushLiteral(envPtr, word, numBytes); } -- cgit v0.12