Skip to content

Commit c8cc233

Browse files
iluuu1994bwoebi
andcommitted
Fix properties_info_table for abstract properties
Fixes GH-19053 Closes GH-19140 Co-authored-by: Bob Weinand <bobwei9@hotmail.com>
1 parent f8196a5 commit c8cc233

File tree

3 files changed

+45
-2
lines changed

3 files changed

+45
-2
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 GH-19169 build issue with C++17 and ZEND_STATIC_ASSERT macro.
77
(psumbera)
8+
. Fixed bug GH-19053 (Duplicate property slot with hooks and interface
9+
property). (ilutov)
810

911
- Hash:
1012
. Fix crash on clone failure. (nielsdos)

Zend/tests/gh19053.phpt

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
--TEST--
2+
GH-19053: Incorrect properties_info_table for abstract properties
3+
--FILE--
4+
<?php
5+
6+
abstract class GP {
7+
public abstract mixed $foo { get; }
8+
}
9+
10+
class P extends GP {
11+
public mixed $foo = 1;
12+
}
13+
14+
class C extends P {
15+
public mixed $foo { get => 2; }
16+
}
17+
18+
$c = new C;
19+
var_dump($c);
20+
21+
?>
22+
--EXPECTF--
23+
object(C)#%d (0) {
24+
["foo"]=>
25+
uninitialized(mixed)
26+
}

Zend/zend_inheritance.c

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1687,10 +1687,25 @@ void zend_build_properties_info_table(zend_class_entry *ce)
16871687
}
16881688
}
16891689

1690-
ZEND_HASH_MAP_FOREACH_PTR(&ce->properties_info, prop) {
1690+
ZEND_HASH_MAP_FOREACH_STR_KEY_PTR(&ce->properties_info, zend_string *key, prop) {
16911691
if (prop->ce == ce && (prop->flags & ZEND_ACC_STATIC) == 0
16921692
&& !(prop->flags & ZEND_ACC_VIRTUAL)) {
1693-
uint32_t prop_table_offset = OBJ_PROP_TO_NUM(!(prop->prototype->flags & ZEND_ACC_VIRTUAL) ? prop->prototype->offset : prop->offset);
1693+
const zend_property_info *root_prop = prop->prototype;
1694+
if (UNEXPECTED(root_prop->flags & ZEND_ACC_VIRTUAL)) {
1695+
/* Prototype is virtual, we need to manually hunt down the first backed property. */
1696+
root_prop = prop;
1697+
zend_class_entry *parent_ce;
1698+
while ((parent_ce = root_prop->ce->parent)) {
1699+
zend_property_info *parent_prop = zend_hash_find_ptr(&parent_ce->properties_info, key);
1700+
if (!parent_prop
1701+
|| parent_prop->prototype != prop->prototype
1702+
|| (parent_prop->flags & ZEND_ACC_VIRTUAL)) {
1703+
break;
1704+
}
1705+
root_prop = parent_prop;
1706+
}
1707+
}
1708+
uint32_t prop_table_offset = OBJ_PROP_TO_NUM(root_prop->offset);
16941709
table[prop_table_offset] = prop;
16951710
}
16961711
} ZEND_HASH_FOREACH_END();

0 commit comments

Comments
 (0)