Skip to content

Commit 155df25

Browse files
committed
Fix phpGH-17736: Assertion failure zend_reference_destroy()
The cache slot for FETCH_OBJ_W in function `test` is primed with the class for C. The next call uses a simplexml instance and reuses the same cache slot. simplexml's get_property_ptr handler does not use the cache slot, so the old values remain in the cache slot. When `zend_handle_fetch_obj_flags` is called this is not guarded by a check for the class entry. So we end up using the prop_info from the property C::$a instead of the simplexml property. This patch adds a check for the class entry. I placed the check as late as possible to avoid as much overhead as possible. An alternative solution is to write NULLs to the cache slot in the get_property_ptr handlers of extensions that don't use the cache slot, but that is not general: not only simplexml would need changes, maybe even third party extensions would need changes as well.
1 parent f8b57ff commit 155df25

File tree

2 files changed

+21
-1
lines changed

2 files changed

+21
-1
lines changed

Zend/zend_execute.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -3267,7 +3267,7 @@ static zend_always_inline void zend_fetch_property_address(zval *result, zval *c
32673267

32683268
if (prop_op_type == IS_CONST) {
32693269
prop_info = CACHED_PTR_EX(cache_slot + 2);
3270-
if (prop_info) {
3270+
if (prop_info && EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) {
32713271
if (UNEXPECTED(!zend_handle_fetch_obj_flags(result, ptr, NULL, prop_info, flags))) {
32723272
goto end;
32733273
}

ext/simplexml/tests/gh17736.phpt

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
--TEST--
2+
GH-17736 (Assertion failure zend_reference_destroy())
3+
--EXTENSIONS--
4+
simplexml
5+
--FILE--
6+
<?php
7+
$o1 = new SimpleXMlElement('<a/>');
8+
class C {
9+
public int $a = 1;
10+
}
11+
function test($obj) {
12+
$ref =& $obj->a;
13+
}
14+
$obj = new C;
15+
test($obj);
16+
test($o1);
17+
echo "Done\n";
18+
?>
19+
--EXPECT--
20+
Done

0 commit comments

Comments
 (0)