Skip to content

Commit 493c91c

Browse files
committed
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.
1 parent 724c4fb commit 493c91c

File tree

2 files changed

+21
-0
lines changed

2 files changed

+21
-0
lines changed

Zend/Optimizer/zend_cfg.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -437,6 +437,9 @@ ZEND_API int zend_build_cfg(zend_arena **arena, const zend_op_array *op_array, u
437437
case ZEND_FE_FREE:
438438
if (zend_optimizer_is_loop_var_free(opline)) {
439439
BB_START(i);
440+
if (i + 1 < op_array->last) {
441+
BB_START(i + 1);
442+
}
440443
flags |= ZEND_FUNC_FREE_LOOP_VAR;
441444
}
442445
break;

Zend/tests/match/045.phpt

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
--TEST--
2+
Corrupted CFG due to unreachable free with match
3+
--FILE--
4+
<?php
5+
function test() {
6+
var_dump(match(x){});
7+
match(y){
8+
3, 4 => 5,
9+
};
10+
}
11+
try {
12+
test();
13+
} catch (Error $e) {
14+
echo $e->getMessage(), "\n";
15+
}
16+
?>
17+
--EXPECT--
18+
Undefined constant "x"

0 commit comments

Comments
 (0)