Skip to content

Commit 398cfb9

Browse files
committed
Don't treat failed assignment as initialization
Only reset the uninitialized property flag once the type check has succeeded. Previously the property was treated as unset rather than uninitialized after a failed assignment. Noticed this edge-case while working on accessors...
1 parent 5ce0fa2 commit 398cfb9

File tree

2 files changed

+37
-1
lines changed

2 files changed

+37
-1
lines changed
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
--TEST--
2+
A failed assignment should not be considered an initialization
3+
--FILE--
4+
<?php
5+
6+
class Test {
7+
public int $prop;
8+
9+
public function __get($name) {
10+
echo "__get() called\n";
11+
return 0;
12+
}
13+
}
14+
15+
$test = new Test;
16+
try {
17+
$test->prop;
18+
} catch (Error $e) {
19+
echo $e->getMessage(), "\n";
20+
}
21+
try {
22+
$test->prop = "foo";
23+
} catch (Error $e) {
24+
echo $e->getMessage(), "\n";
25+
}
26+
try {
27+
$test->prop;
28+
} catch (Error $e) {
29+
echo $e->getMessage(), "\n";
30+
}
31+
32+
?>
33+
--EXPECT--
34+
Typed property Test::$prop must not be accessed before initialization
35+
Cannot assign string to property Test::$prop of type int
36+
Typed property Test::$prop must not be accessed before initialization

Zend/zend_object_handlers.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -728,7 +728,6 @@ ZEND_API zval *zend_std_write_property(zend_object *zobj, zend_string *name, zva
728728
}
729729
if (Z_PROP_FLAG_P(variable_ptr) == IS_PROP_UNINIT) {
730730
/* Writes to uninitializde typed properties bypass __set(). */
731-
Z_PROP_FLAG_P(variable_ptr) = 0;
732731
goto write_std_property;
733732
}
734733
} else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(property_offset))) {
@@ -783,6 +782,7 @@ ZEND_API zval *zend_std_write_property(zend_object *zobj, zend_string *name, zva
783782
goto exit;
784783
}
785784
value = &tmp;
785+
Z_PROP_FLAG_P(variable_ptr) = 0;
786786
goto found; /* might have been updated via e.g. __toString() */
787787
}
788788

0 commit comments

Comments
 (0)