Skip to content

Commit c9a4aba

Browse files
committed
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. Closes GH-15891.
1 parent 31e2ec6 commit c9a4aba

File tree

3 files changed

+46
-0
lines changed

3 files changed

+46
-0
lines changed

NEWS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ PHP NEWS
1010
. Fix XML serializer errata: xmlns="" serialization should be allowed.
1111
(nielsdos)
1212
. Fixed bug GH-15910 (Assertion failure in ext/dom/element.c). (nielsdos)
13+
. Fix unsetting DOM properties. (nielsdos)
1314

1415
- MBString:
1516
. Fixed bug GH-15824 (mb_detect_encoding(): Argument $encodings contains

ext/dom/php_dom.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -478,6 +478,18 @@ static int dom_property_exists(zend_object *object, zend_string *name, int check
478478
}
479479
/* }}} */
480480

481+
static void dom_unset_property(zend_object *object, zend_string *member, void **cache_slot)
482+
{
483+
dom_object *obj = php_dom_obj_from_obj(object);
484+
485+
if (obj->prop_handler != NULL && zend_hash_exists(obj->prop_handler, member)) {
486+
zend_throw_error(NULL, "Cannot unset %s::$%s", ZSTR_VAL(object->ce->name), ZSTR_VAL(member));
487+
return;
488+
}
489+
490+
zend_std_unset_property(object, member, cache_slot);
491+
}
492+
481493
static HashTable* dom_get_debug_info_helper(zend_object *object, int *is_temp) /* {{{ */
482494
{
483495
dom_object *obj = php_dom_obj_from_obj(object);
@@ -755,6 +767,7 @@ PHP_MINIT_FUNCTION(dom)
755767
dom_object_handlers.read_property = dom_read_property;
756768
dom_object_handlers.write_property = dom_write_property;
757769
dom_object_handlers.get_property_ptr_ptr = dom_get_property_ptr_ptr;
770+
dom_object_handlers.unset_property = dom_unset_property;
758771
dom_object_handlers.clone_obj = dom_objects_store_clone_obj;
759772
dom_object_handlers.has_property = dom_property_exists;
760773
dom_object_handlers.get_debug_info = dom_get_debug_info;
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
--TEST--
2+
Unsetting properties
3+
--EXTENSIONS--
4+
dom
5+
--FILE--
6+
<?php
7+
8+
class MyElement extends DOMElement {
9+
public int $myProp = 3;
10+
}
11+
12+
$dom = new DOMDocument;
13+
$dom->registerNodeClass('DOMElement', 'MyElement');
14+
$dom->loadXML('<root>foo</root>');
15+
$root = $dom->documentElement;
16+
17+
unset($root->myProp);
18+
try {
19+
$root->myProp;
20+
} catch (Error $e) {
21+
echo $e->getMessage(), "\n";
22+
}
23+
try {
24+
unset($root->textContent);
25+
} catch (Error $e) {
26+
echo $e->getMessage(), "\n";
27+
}
28+
29+
?>
30+
--EXPECT--
31+
Typed property MyElement::$myProp must not be accessed before initialization
32+
Cannot unset MyElement::$textContent

0 commit comments

Comments
 (0)