diff options
| author | sebres <sebres@users.sourceforge.net> | 2024-08-12 13:19:34 (GMT) |
|---|---|---|
| committer | sebres <sebres@users.sourceforge.net> | 2024-08-12 13:19:34 (GMT) |
| commit | 2326287079501642fa96f68c988af53a5e92a6b9 (patch) | |
| tree | e7d548ed1985998a04b9dabb63db7d4a0828b68b | |
| parent | 2dc0fb6f2a5d96240df65fba871e82a3d34b592b (diff) | |
| parent | 7c603bb3f40a4c0f2903eecb0ea92d9bfec5eb55 (diff) | |
| download | tcl-2326287079501642fa96f68c988af53a5e92a6b9.zip tcl-2326287079501642fa96f68c988af53a5e92a6b9.tar.gz tcl-2326287079501642fa96f68c988af53a5e92a6b9.tar.bz2 | |
merge fix for [7179c6724cd38271]: compilation of incr command on wide constant offset (no overflow) + test coverage
| -rw-r--r-- | generic/tclCompCmdsGR.c | 11 | ||||
| -rw-r--r-- | tests/incr.test | 56 |
2 files changed, 65 insertions, 2 deletions
diff --git a/generic/tclCompCmdsGR.c b/generic/tclCompCmdsGR.c index 7efe6ae..8143c9e 100644 --- a/generic/tclCompCmdsGR.c +++ b/generic/tclCompCmdsGR.c @@ -507,10 +507,17 @@ TclCompileIncrCmd( 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) + /* 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)) + ) + ) { haveImmValue = 1; } + TclDecrRefCount(intObj); if (!haveImmValue) { PushLiteral(envPtr, word, numBytes); } diff --git a/tests/incr.test b/tests/incr.test index af15f5e..ff328b7 100644 --- a/tests/incr.test +++ b/tests/incr.test @@ -236,6 +236,62 @@ test incr-1.30 {TclCompileIncrCmd: array var, braced (no subs)} -setup { incr {array($foo)} } -result 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. unset -nocomplain x i |
