Thanks to Zellic and @fcremo for the find and fix!
The guard in get_successors was intended to prevent an overflow, but the check erroneously assumed that the last instruction was a return or an abort. In the case that it was an unconditional jump, the successors would not be captured in the CFG. And as such, the target code would not be visited (if this was the only predecessor). This means that locals safety and reference safety (and any custom, control flow based checks) would not be run on the skipped code.
Motivation
Thanks to Zellic and @fcremo for the find and fix!
The guard in
get_successors
was intended to prevent an overflow, but the check erroneously assumed that the last instruction was a return or an abort. In the case that it was an unconditional jump, the successors would not be captured in the CFG. And as such, the target code would not be visited (if this was the only predecessor). This means that locals safety and reference safety (and any custom, control flow based checks) would not be run on the skipped code.Test Plan