Merge branch 'PHP-8.4'

* PHP-8.4:
  Fix properties_info_table for abstract properties
This commit is contained in:
Ilija Tovilo 2025-07-21 15:54:53 +02:00
commit d20f4fca69
No known key found for this signature in database
GPG key ID: 5050C66BFCD1015A
2 changed files with 43 additions and 2 deletions

26
Zend/tests/gh19053.phpt Normal file
View file

@ -0,0 +1,26 @@
--TEST--
GH-19053: Incorrect properties_info_table for abstract properties
--FILE--
<?php
abstract class GP {
public abstract mixed $foo { get; }
}
class P extends GP {
public mixed $foo = 1;
}
class C extends P {
public mixed $foo { get => 2; }
}
$c = new C;
var_dump($c);
?>
--EXPECTF--
object(C)#%d (0) {
["foo"]=>
uninitialized(mixed)
}

View file

@ -1713,10 +1713,25 @@ void zend_build_properties_info_table(zend_class_entry *ce)
}
}
ZEND_HASH_MAP_FOREACH_PTR(&ce->properties_info, prop) {
ZEND_HASH_MAP_FOREACH_STR_KEY_PTR(&ce->properties_info, zend_string *key, prop) {
if (prop->ce == ce && (prop->flags & ZEND_ACC_STATIC) == 0
&& !(prop->flags & ZEND_ACC_VIRTUAL)) {
uint32_t prop_table_offset = OBJ_PROP_TO_NUM(!(prop->prototype->flags & ZEND_ACC_VIRTUAL) ? prop->prototype->offset : prop->offset);
const zend_property_info *root_prop = prop->prototype;
if (UNEXPECTED(root_prop->flags & ZEND_ACC_VIRTUAL)) {
/* Prototype is virtual, we need to manually hunt down the first backed property. */
root_prop = prop;
zend_class_entry *parent_ce;
while ((parent_ce = root_prop->ce->parent)) {
zend_property_info *parent_prop = zend_hash_find_ptr(&parent_ce->properties_info, key);
if (!parent_prop
|| parent_prop->prototype != prop->prototype
|| (parent_prop->flags & ZEND_ACC_VIRTUAL)) {
break;
}
root_prop = parent_prop;
}
}
uint32_t prop_table_offset = OBJ_PROP_TO_NUM(root_prop->offset);
table[prop_table_offset] = prop;
}
} ZEND_HASH_FOREACH_END();