]> granicus.if.org Git - php/commitdiff
Fix #79065: DOM classes do not expose properties to Reflection
authorChristoph M. Becker <cmbecker69@gmx.de>
Tue, 21 Apr 2020 11:28:01 +0000 (13:28 +0200)
committerChristoph M. Becker <cmbecker69@gmx.de>
Mon, 27 Apr 2020 08:04:29 +0000 (10:04 +0200)
We add a `get_properties` handler which complements the already
existing `has_property` and `read_property`handlers.

NEWS
ext/dom/php_dom.c
ext/dom/tests/bug79065.phpt [new file with mode: 0644]

diff --git a/NEWS b/NEWS
index ba008a7ba7f7cffca93154d1a4a91649413617c3..0fecf66f7f79d1e1553a48b50db1b9d32a22b1bb 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -16,6 +16,8 @@ PHP                                                                        NEWS
 - DOM:
   . Fixed bug #78221 (DOMNode::normalize() doesn't remove empty text nodes).
     (cmb)
+  . Fixed bug #79065 (DOM classes do not expose properties to Reflection).
+    (cmb)
 
 - EXIF:
   . Fixed bug #79336 (ext/exif/tests/bug79046.phpt fails on Big endian arch).
index 6bc72e9f9794032a20324ced797a4c189595d822..ad297ca7788fb67474786460079790f677e44927 100644 (file)
@@ -410,6 +410,28 @@ static int dom_property_exists(zval *object, zval *member, int check_empty, void
 }
 /* }}} */
 
+/* {{{ dom_get_properties */
+static HashTable *dom_get_properties(zval *object)
+{
+       dom_object *obj = Z_DOMOBJ_P(object);
+       HashTable *props = zend_std_get_properties(object);
+
+       if (obj->prop_handler != NULL) {
+               zend_string *key;
+               dom_prop_handler *hnd;
+
+               ZEND_HASH_FOREACH_STR_KEY_PTR(obj->prop_handler, key, hnd) {
+                       zval val;
+
+                       if (hnd->read_func(obj, &val) == SUCCESS) {
+                               zend_hash_update(props, key, &val);
+                       }
+               } ZEND_HASH_FOREACH_END();
+       }
+       return props;
+}
+/* }}} */
+
 static HashTable* dom_get_debug_info_helper(zval *object, int *is_temp) /* {{{ */
 {
        dom_object                      *obj = Z_DOMOBJ_P(object);
@@ -602,6 +624,7 @@ PHP_MINIT_FUNCTION(dom)
        dom_object_handlers.get_property_ptr_ptr = dom_get_property_ptr_ptr;
        dom_object_handlers.clone_obj = dom_objects_store_clone_obj;
        dom_object_handlers.has_property = dom_property_exists;
+       dom_object_handlers.get_properties = dom_get_properties;
        dom_object_handlers.get_debug_info = dom_get_debug_info;
 
        memcpy(&dom_nnodemap_object_handlers, &dom_object_handlers, sizeof(zend_object_handlers));
diff --git a/ext/dom/tests/bug79065.phpt b/ext/dom/tests/bug79065.phpt
new file mode 100644 (file)
index 0000000..9f3f49b
--- /dev/null
@@ -0,0 +1,30 @@
+--TEST--
+Bug #79065 (DOM classes do not expose properties to Reflection)
+--SKIPIF--
+<?php
+if (!extension_loaded('dom')) die('skip dom extension not available');
+?>
+--FILE--
+<?php
+$dom = new DOMDocument;
+$dom->loadHTML('<b>test</b>');
+var_dump(count(get_object_vars($dom)));
+
+$ro = new ReflectionObject($dom);
+var_dump(count($ro->getProperties()));
+var_dump($ro->hasProperty("textContent"));
+$rp = $ro->getProperty("textContent");
+var_dump($rp);
+var_dump($rp->getValue($dom));
+?>
+--EXPECTF--
+int(35)
+int(35)
+bool(true)
+object(ReflectionProperty)#%d (2) {
+  ["name"]=>
+  string(11) "textContent"
+  ["class"]=>
+  string(11) "DOMDocument"
+}
+string(4) "test"