Skip to content

Commit dfaa476

Browse files
committed
Fix bug #80037
If we're accessing an uninitialized typed property and __get is defined, don't perform a read_property callback, as __get is supposed to have no effect on uninitialized typed properties. Usually it doesn't, but by-reference assignments cannot be performed through read_property. I'm deleting the test for bug #80039 again, as it doesn't really make sense anymore with this fix.
1 parent 8f7c529 commit dfaa476

File tree

4 files changed

+36
-44
lines changed

4 files changed

+36
-44
lines changed

NEWS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ PHP NEWS
55
- Core:
66
. Fixed bug #79979 (passing value to by-ref param via CUFA crashes). (cmb,
77
Nikita)
8+
. Fixed bug #80037 (Typed property must not be accessed before initialization
9+
when __get() declared). (Nikita)
810

911
- Calendar:
1012
. Fixed bug #80007 (Potential type confusion in unixtojd() parameter parsing).

Zend/tests/bug80037.phpt

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
--TEST--
2+
Bug #80037: Typed property must not be accessed before initialization when __get() declared
3+
--FILE--
4+
<?php
5+
6+
final class A
7+
{
8+
public string $a;
9+
10+
public static function fromArray(array $props): self
11+
{
12+
$me = new static;
13+
foreach ($props as $k => &$v) {
14+
$me->{$k} = &$v; # try to remove &
15+
}
16+
return $me;
17+
}
18+
19+
public function __get($name)
20+
{
21+
throw new \LogicException("Property '$name' is not defined.");
22+
}
23+
}
24+
25+
var_dump(A::fromArray(['a' => 'foo']));
26+
27+
?>
28+
--EXPECT--
29+
object(A)#1 (1) {
30+
["a"]=>
31+
string(3) "foo"
32+
}

Zend/tests/bug80039.phpt

Lines changed: 0 additions & 43 deletions
This file was deleted.

Zend/zend_object_handlers.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1051,7 +1051,8 @@ ZEND_API zval *zend_std_get_property_ptr_ptr(zval *object, zval *member, int typ
10511051
retval = OBJ_PROP(zobj, property_offset);
10521052
if (UNEXPECTED(Z_TYPE_P(retval) == IS_UNDEF)) {
10531053
if (EXPECTED(!zobj->ce->__get) ||
1054-
UNEXPECTED((*zend_get_property_guard(zobj, name)) & IN_GET)) {
1054+
UNEXPECTED((*zend_get_property_guard(zobj, name)) & IN_GET) ||
1055+
UNEXPECTED(prop_info && Z_PROP_FLAG_P(retval) == IS_PROP_UNINIT)) {
10551056
if (UNEXPECTED(type == BP_VAR_RW || type == BP_VAR_R)) {
10561057
if (UNEXPECTED(prop_info)) {
10571058
zend_throw_error(NULL,

0 commit comments

Comments
 (0)