diff options
author | Kevin B Kenny <kennykb@acm.org> | 2016-05-13 00:46:23 (GMT) |
---|---|---|
committer | Kevin B Kenny <kennykb@acm.org> | 2016-05-13 00:46:23 (GMT) |
commit | c2cac5959d1949fd3e19ff977d28c9adfc872466 (patch) | |
tree | 1a4b44ff6ef696bc6e1dca3f607952bb4d6c55d8 | |
parent | 8de5d7db9521a7768f47f53adfa6ef41a2072ca9 (diff) | |
parent | 675a0b7982d2ef03a79ee18e5f85aed8a2d34698 (diff) | |
download | tcl-c2cac5959d1949fd3e19ff977d28c9adfc872466.zip tcl-c2cac5959d1949fd3e19ff977d28c9adfc872466.tar.gz tcl-c2cac5959d1949fd3e19ff977d28c9adfc872466.tar.bz2 |
Bug fix: Assembler dereferences a rogue pointer when unstacking an empty exception range.
-rw-r--r-- | generic/tclAssembly.c | 10 | ||||
-rw-r--r-- | tests/assemble.test | 85 |
2 files changed, 91 insertions, 4 deletions
diff --git a/generic/tclAssembly.c b/generic/tclAssembly.c index 4ad31d2..8dd23a0 100644 --- a/generic/tclAssembly.c +++ b/generic/tclAssembly.c @@ -3982,10 +3982,12 @@ UnstackExpiredCatches( while (catchDepth > bbPtr->catchDepth) { --catchDepth; - range = envPtr->exceptArrayPtr + catchIndices[catchDepth]; - range->numCodeBytes = bbPtr->startOffset - range->codeOffset; - catches[catchDepth] = NULL; - catchIndices[catchDepth] = -1; + if (catches[catchDepth] != NULL) { + range = envPtr->exceptArrayPtr + catchIndices[catchDepth]; + range->numCodeBytes = bbPtr->startOffset - range->codeOffset; + catches[catchDepth] = NULL; + catchIndices[catchDepth] = -1; + } } /* diff --git a/tests/assemble.test b/tests/assemble.test index 5c226cd..7c65595 100644 --- a/tests/assemble.test +++ b/tests/assemble.test @@ -3279,6 +3279,91 @@ test assemble-51.4 {memory leak testing} memory { } } } 0 + +test assemble-52.1 {Bug 3154ea2759} { + proc __BEGIN {} { + ::tcl::unsupported::assemble { + beginCatch @badLabel + push error + push testing + invokeStk 2 + pop + push 0 + jump @okLabel + label @badLabel + push 1; # should be pushReturnCode + label @okLabel + endCatch + pop + + beginCatch @badLabel2 + push error + push testing + invokeStk 2 + pop + push 0 + jump @okLabel2 + label @badLabel2 + push 1; # should be pushReturnCode + label @okLabel2 + endCatch + pop + + beginCatch @badLabel3 + push error + push testing + invokeStk 2 + pop + push 0 + jump @okLabel3 + label @badLabel3 + push 1; # should be pushReturnCode + label @okLabel3 + endCatch + pop + + beginCatch @badLabel4 + push error + push testing + invokeStk 2 + pop + push 0 + jump @okLabel4 + label @badLabel4 + push 1; # should be pushReturnCode + label @okLabel4 + endCatch + pop + + beginCatch @badLabel5 + push error + push testing + invokeStk 2 + pop + push 0 + jump @okLabel5 + label @badLabel5 + push 1; # should be pushReturnCode + label @okLabel5 + endCatch + pop + + beginCatch @badLabel6 + push error + push testing + invokeStk 2 + pop + push 0 + jump @okLabel6 + label @badLabel6 + push 1; # should be pushReturnCode + label @okLabel6 + endCatch + pop + } + } + __BEGIN +} {}; # must not crash rename fillTables {} rename assemble {} |