Skip to content

Commit ca3f7b0

Browse files
committed
Merge branch 'PHP-8.0' into PHP-8.1
* PHP-8.0: Fix incorrect optimization of ASSIGN_OP that may lead to memory leak
2 parents 3e84217 + e004e84 commit ca3f7b0

File tree

2 files changed

+40
-3
lines changed

2 files changed

+40
-3
lines changed

Zend/Optimizer/dfa_pass.c

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -333,7 +333,7 @@ static inline bool can_elide_return_type_check(
333333
}
334334

335335
static bool opline_supports_assign_contraction(
336-
zend_ssa *ssa, zend_op *opline, int src_var, uint32_t cv_var) {
336+
zend_op_array *op_array, zend_ssa *ssa, zend_op *opline, int src_var, uint32_t cv_var) {
337337
if (opline->opcode == ZEND_NEW) {
338338
/* see Zend/tests/generators/aborted_yield_during_new.phpt */
339339
return 0;
@@ -367,6 +367,13 @@ static bool opline_supports_assign_contraction(
367367
return opline->op1_type != IS_CV || opline->op1.var != cv_var;
368368
}
369369

370+
if (opline->opcode == ZEND_ASSIGN_OP
371+
&& opline->op1_type == IS_CV
372+
&& opline->op1.var == cv_var
373+
&& zend_may_throw(opline, &ssa->ops[ssa->vars[src_var].definition], op_array, ssa)) {
374+
return 0;
375+
}
376+
370377
return 1;
371378
}
372379

@@ -1357,7 +1364,7 @@ void zend_dfa_optimize_op_array(zend_op_array *op_array, zend_optimizer_ctx *ctx
13571364
&& !ssa->vars[src_var].phi_use_chain
13581365
&& !ssa->vars[src_var].sym_use_chain
13591366
&& opline_supports_assign_contraction(
1360-
ssa, &op_array->opcodes[ssa->vars[src_var].definition],
1367+
op_array, ssa, &op_array->opcodes[ssa->vars[src_var].definition],
13611368
src_var, opline->result.var)
13621369
&& !variable_defined_or_used_in_range(ssa, EX_VAR_TO_NUM(opline->result.var),
13631370
ssa->vars[src_var].definition+1, op_1)
@@ -1514,7 +1521,7 @@ void zend_dfa_optimize_op_array(zend_op_array *op_array, zend_optimizer_ctx *ctx
15141521
&& !ssa->vars[src_var].phi_use_chain
15151522
&& !ssa->vars[src_var].sym_use_chain
15161523
&& opline_supports_assign_contraction(
1517-
ssa, &op_array->opcodes[ssa->vars[src_var].definition],
1524+
op_array, ssa, &op_array->opcodes[ssa->vars[src_var].definition],
15181525
src_var, opline->op1.var)
15191526
&& !variable_defined_or_used_in_range(ssa, EX_VAR_TO_NUM(opline->op1.var),
15201527
ssa->vars[src_var].definition+1, op_1)
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
--TEST--
2+
ASSIGN_OP 001: Incrrect optimization of ASSIGN_OP may lead to memory leak
3+
--INI--
4+
opcache.enable=1
5+
opcache.enable_cli=1
6+
opcache.optimization_level=-1
7+
--FILE--
8+
<?php
9+
function test() {
10+
for ($i = 0; $i < 10; $i++) {
11+
$a = $a += $a < true;
12+
$a += $a;
13+
$a = [];
14+
$a['b'] += 1;
15+
}
16+
}
17+
test();
18+
?>
19+
--EXPECTF--
20+
Warning: Undefined variable $a in %sassign_op_001.php on line 4
21+
22+
Warning: Undefined variable $a in %sassign_op_001.php on line 4
23+
24+
Warning: Undefined array key "b" in %sassign_op_001.php on line 7
25+
26+
Fatal error: Uncaught TypeError: Unsupported operand types: array + bool in %sassign_op_001.php:4
27+
Stack trace:
28+
#0 %sassign_op_001.php(10): test()
29+
#1 {main}
30+
thrown in %sassign_op_001.php on line 4

0 commit comments

Comments
 (0)