Skip to content

Commit eecbb60

Browse files
committed
Fix memory leak
Fixes oss-fuzz #52479
1 parent d282345 commit eecbb60

File tree

3 files changed

+27
-2
lines changed

3 files changed

+27
-2
lines changed

Zend/Optimizer/zend_cfg.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -297,12 +297,12 @@ ZEND_API void zend_build_cfg(zend_arena **arena, const zend_op_array *op_array,
297297
case ZEND_RETURN:
298298
case ZEND_RETURN_BY_REF:
299299
case ZEND_GENERATOR_RETURN:
300-
case ZEND_MATCH_ERROR:
301300
case ZEND_VERIFY_NEVER_TYPE:
302301
if (i + 1 < op_array->last) {
303302
BB_START(i + 1);
304303
}
305304
break;
305+
case ZEND_MATCH_ERROR:
306306
case ZEND_EXIT:
307307
case ZEND_THROW:
308308
/* Don't treat THROW as terminator if it's used in expression context,
@@ -428,7 +428,9 @@ ZEND_API void zend_build_cfg(zend_arena **arena, const zend_op_array *op_array,
428428
break;
429429
case ZEND_FREE:
430430
case ZEND_FE_FREE:
431-
if (zend_optimizer_is_loop_var_free(opline)) {
431+
if (zend_optimizer_is_loop_var_free(opline)
432+
&& ((opline-1)->opcode != ZEND_MATCH_ERROR
433+
|| (opline-1)->extended_value != ZEND_THROW_IS_EXPR)) {
432434
BB_START(i);
433435
flags |= ZEND_FUNC_FREE_LOOP_VAR;
434436
}

Zend/zend_compile.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5776,6 +5776,10 @@ static void zend_compile_match(znode *result, zend_ast *ast)
57765776
if (opline->op1_type == IS_CONST) {
57775777
Z_TRY_ADDREF_P(CT_CONSTANT(opline->op1));
57785778
}
5779+
if (arms->children == 0) {
5780+
/* Mark this as an "expression throw" for opcache. */
5781+
opline->extended_value = ZEND_THROW_IS_EXPR;
5782+
}
57795783
}
57805784

57815785
for (uint32_t i = 0; i < arms->children; ++i) {

ext/opcache/tests/opt/match_001.phpt

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
--TEST--
2+
Match 001: memory leak because of live range lose
3+
--INI--
4+
opcache.enable=1
5+
opcache.enable_cli=1
6+
opcache.optimization_level=-1
7+
--FILE--
8+
<?php
9+
+$y . +$y . match(y) {}
10+
?>
11+
--EXPECTF--
12+
Warning: Undefined variable $y in %smatch_001.php on line 2
13+
14+
Warning: Undefined variable $y in %smatch_001.php on line 2
15+
16+
Fatal error: Uncaught Error: Undefined constant "y" in %smatch_001.php:2
17+
Stack trace:
18+
#0 {main}
19+
thrown in %smatch_001.php on line 2

0 commit comments

Comments
 (0)