Start new block after loop free

In the attached test case we ended up not updating a leftover
MATCH jump in the unreachable_free block. There's different ways
this can be addressed, but in this case we can just make sure that
a new block is started after the loop free, which will allow it
to be dropped as unreachable. We only need to retain the free
itself for live-range reconstruction.

Fixes oss-fuzz #39516.
This commit is contained in:
Nikita Popov 2021-10-04 16:41:27 +02:00
parent 724c4fb2e5
commit 493c91c742
2 changed files with 21 additions and 0 deletions

View file

@ -437,6 +437,9 @@ ZEND_API int zend_build_cfg(zend_arena **arena, const zend_op_array *op_array, u
case ZEND_FE_FREE:
if (zend_optimizer_is_loop_var_free(opline)) {
BB_START(i);
if (i + 1 < op_array->last) {
BB_START(i + 1);
}
flags |= ZEND_FUNC_FREE_LOOP_VAR;
}
break;

18
Zend/tests/match/045.phpt Normal file
View file

@ -0,0 +1,18 @@
--TEST--
Corrupted CFG due to unreachable free with match
--FILE--
<?php
function test() {
var_dump(match(x){});
match(y){
3, 4 => 5,
};
}
try {
test();
} catch (Error $e) {
echo $e->getMessage(), "\n";
}
?>
--EXPECT--
Undefined constant "x"