Skip to content

Commit 885b345

Browse files
committed
Fix early free of assign_obj op_data
We need to make sure that op_data is only freed after populating result, as op_data may be the only thing holding the value in the case of an overloaded assignment. This reverts the code to how it looked like in 7.3.
1 parent 66d5b06 commit 885b345

File tree

3 files changed

+310
-74
lines changed

3 files changed

+310
-74
lines changed
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
--TEST--
2+
Make sure the return value of a property assignment is not freed to early
3+
--FILE--
4+
<?php
5+
class Overloaded {
6+
function __set($r, $a) {}
7+
}
8+
$obj = new Overloaded;
9+
$x = $obj->prop = new stdClass;
10+
var_dump($x);
11+
?>
12+
--EXPECT--
13+
object(stdClass)#2 (0) {
14+
}

Zend/zend_vm_def.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2495,6 +2495,9 @@ ZEND_VM_C_LABEL(assign_object):
24952495
} else {
24962496
ZEND_VM_C_LABEL(fast_assign_obj):
24972497
value = zend_assign_to_variable(property_val, value, OP_DATA_TYPE, EX_USES_STRICT_TYPES());
2498+
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
2499+
ZVAL_COPY(EX_VAR(opline->result.var), value);
2500+
}
24982501
ZEND_VM_C_GOTO(exit_assign_obj);
24992502
}
25002503
}
@@ -2542,6 +2545,9 @@ ZEND_VM_C_LABEL(fast_assign_obj):
25422545
}
25432546
}
25442547
zend_hash_add_new(zobj->properties, Z_STR_P(property), value);
2548+
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
2549+
ZVAL_COPY(EX_VAR(opline->result.var), value);
2550+
}
25452551
ZEND_VM_C_GOTO(exit_assign_obj);
25462552
}
25472553
}
@@ -2554,11 +2560,11 @@ ZEND_VM_C_LABEL(fast_assign_obj):
25542560
value = Z_OBJ_HT_P(object)->write_property(object, property, value, (OP2_TYPE == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
25552561

25562562
ZEND_VM_C_LABEL(free_and_exit_assign_obj):
2557-
FREE_OP_DATA();
2558-
ZEND_VM_C_LABEL(exit_assign_obj):
25592563
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
25602564
ZVAL_COPY(EX_VAR(opline->result.var), value);
25612565
}
2566+
FREE_OP_DATA();
2567+
ZEND_VM_C_LABEL(exit_assign_obj):
25622568
FREE_OP2();
25632569
FREE_OP1_VAR_PTR();
25642570
/* assign_obj has two opcodes! */

0 commit comments

Comments
 (0)