From be79005ce4a5722ad8653e726f3b356c4789db7c Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Sat, 31 Aug 2024 11:44:20 +0200 Subject: [PATCH] Fix GH-15670: Polymorphic cache slot issue in DOM A cache slot can be hit with different DOM object types, so we should check if we're still handling the same type. --- ext/dom/php_dom.c | 12 +++++++----- ext/dom/tests/gh15670.phpt | 29 +++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 5 deletions(-) create mode 100644 ext/dom/tests/gh15670.phpt diff --git a/ext/dom/php_dom.c b/ext/dom/php_dom.c index 42a6876b414b..bf2eb826fcb1 100644 --- a/ext/dom/php_dom.c +++ b/ext/dom/php_dom.c @@ -370,13 +370,14 @@ static zend_always_inline const dom_prop_handler *dom_get_prop_handler(const dom const dom_prop_handler *hnd = NULL; if (obj->prop_handler != NULL) { - if (cache_slot) { - hnd = *cache_slot; + if (cache_slot && *cache_slot == obj->prop_handler) { + hnd = *(cache_slot + 1); } if (!hnd) { hnd = zend_hash_find_ptr(obj->prop_handler, name); if (cache_slot) { - *cache_slot = (void *) hnd; + *cache_slot = obj->prop_handler; + *(cache_slot + 1) = (void *) hnd; } } } @@ -419,12 +420,13 @@ zval *dom_write_property(zend_object *object, zend_string *name, zval *value, vo zend_property_info *prop = NULL; if (cache_slot) { - prop = *(cache_slot + 1); + ZEND_ASSERT(*cache_slot == obj->prop_handler); + prop = *(cache_slot + 2); } if (!prop) { prop = zend_get_property_info(object->ce, name, /* silent */ true); if (cache_slot) { - *(cache_slot + 1) = prop; + *(cache_slot + 2) = prop; } } diff --git a/ext/dom/tests/gh15670.phpt b/ext/dom/tests/gh15670.phpt new file mode 100644 index 000000000000..d042803ae1e3 --- /dev/null +++ b/ext/dom/tests/gh15670.phpt @@ -0,0 +1,29 @@ +--TEST-- +GH-15670 (Polymorphic cache slot issue in DOM) +--EXTENSIONS-- +dom +--FILE-- +loadHTML('
foo
'); +$dom = DOM\XMLDocument::createFromString('