Fix assertion failure in zend_std_read_property

We asserted that Z_PROP_FLAG_P(retval) was exactly IS_PROP_UNINIT, but this is a
bit field and it may contain irrelevant bits. For instance it may contain
IS_PROP_REINITABLE during clone, or IS_PROP_LAZY if the object is lazy.

Fixes GH-16615
Closes GH-16639
This commit is contained in:
Arnaud Le Blanc 2024-10-29 13:02:56 +01:00
parent ef56241483
commit 3d3b22ddf2
No known key found for this signature in database
GPG Key ID: 0098C05DD15ABC13
4 changed files with 49 additions and 1 deletions

1
NEWS
View File

@ -7,6 +7,7 @@ PHP NEWS
(nielsdos)
. Fixed bug GH-16577 (EG(strtod_state).freelist leaks with opcache.preload).
(nielsdos)
. Fixed bug GH-16615 (Assertion failure in zend_std_read_property). (Arnaud)
- DOM:
. Fixed bug GH-16594 (Assertion failure in DOM -> before). (nielsdos)

View File

@ -0,0 +1,23 @@
--TEST--
GH-16615 001 (Assertion failure in zend_std_read_property)
--FILE--
<?php
class Foo {
public string $bar {
set => $value;
}
}
$reflector = new ReflectionClass(Foo::class);
// Adds IS_PROP_LAZY to prop flags
$foo = $reflector->newLazyGhost(function ($ghost) {
$ghost->bar = 'bar';
});
echo $foo->bar;
?>
--EXPECT--
bar

View File

@ -0,0 +1,24 @@
--TEST--
GH-16615 002 (Assertion failure in zend_std_read_property)
--FILE--
<?php
class Foo {
public string $bar {
set => $value;
}
public function __clone() {
try {
echo $this->bar;
} catch (Error $e) {
printf("%s: %s\n", $e::class, $e->getMessage());
}
}
}
// Adds IS_PROP_REINITABLE to prop flags
clone new Foo();
?>
--EXPECT--
Error: Typed property Foo::$bar must not be accessed before initialization

View File

@ -791,7 +791,7 @@ try_again:
if (UNEXPECTED(Z_TYPE_P(retval) == IS_UNDEF)) {
/* As hooked properties can't be unset, the only way to end up with an undef
* value is via an uninitialized property. */
ZEND_ASSERT(Z_PROP_FLAG_P(retval) == IS_PROP_UNINIT);
ZEND_ASSERT(Z_PROP_FLAG_P(retval) & IS_PROP_UNINIT);
goto uninit_error;
}