From 71d3b983b466bf9dae219ed0c4944c8f89340b2c Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Sat, 14 Sep 2024 22:47:24 +0200 Subject: [PATCH] Fix unsetting DOM properties This never did anything in lower versions, but on master this crashes because the virtual properties don't have backing storage. Just forbid it since it was useless to begin with. --- ext/dom/php_dom.c | 13 ++++++++++ ext/dom/tests/unsetting_properties.phpt | 32 +++++++++++++++++++++++++ 2 files changed, 45 insertions(+) create mode 100644 ext/dom/tests/unsetting_properties.phpt diff --git a/ext/dom/php_dom.c b/ext/dom/php_dom.c index 8198afe5b8bad..346436a5627c0 100644 --- a/ext/dom/php_dom.c +++ b/ext/dom/php_dom.c @@ -478,6 +478,18 @@ static int dom_property_exists(zend_object *object, zend_string *name, int check } /* }}} */ +static void dom_unset_property(zend_object *object, zend_string *member, void **cache_slot) +{ + dom_object *obj = php_dom_obj_from_obj(object); + + if (obj->prop_handler != NULL && zend_hash_exists(obj->prop_handler, member)) { + zend_throw_error(NULL, "Cannot unset %s::$%s", ZSTR_VAL(object->ce->name), ZSTR_VAL(member)); + return; + } + + zend_std_unset_property(object, member, cache_slot); +} + static HashTable* dom_get_debug_info_helper(zend_object *object, int *is_temp) /* {{{ */ { dom_object *obj = php_dom_obj_from_obj(object); @@ -755,6 +767,7 @@ PHP_MINIT_FUNCTION(dom) dom_object_handlers.read_property = dom_read_property; dom_object_handlers.write_property = dom_write_property; dom_object_handlers.get_property_ptr_ptr = dom_get_property_ptr_ptr; + dom_object_handlers.unset_property = dom_unset_property; dom_object_handlers.clone_obj = dom_objects_store_clone_obj; dom_object_handlers.has_property = dom_property_exists; dom_object_handlers.get_debug_info = dom_get_debug_info; diff --git a/ext/dom/tests/unsetting_properties.phpt b/ext/dom/tests/unsetting_properties.phpt new file mode 100644 index 0000000000000..ec309c18bf584 --- /dev/null +++ b/ext/dom/tests/unsetting_properties.phpt @@ -0,0 +1,32 @@ +--TEST-- +Unsetting properties +--EXTENSIONS-- +dom +--FILE-- +registerNodeClass('DOMElement', 'MyElement'); +$dom->loadXML('foo'); +$root = $dom->documentElement; + +unset($root->myProp); +try { + $root->myProp; +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} +try { + unset($root->textContent); +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} + +?> +--EXPECT-- +Typed property MyElement::$myProp must not be accessed before initialization +Cannot unset MyElement::$textContent