]> granicus.if.org Git - php/commitdiff
Improved on DOM object debug info handler. Added test.
authorGustavo André dos Santos Lopes <cataphract@php.net>
Thu, 22 Mar 2012 21:49:04 +0000 (21:49 +0000)
committerGustavo André dos Santos Lopes <cataphract@php.net>
Fri, 23 Mar 2012 21:23:24 +0000 (21:23 +0000)
ext/dom/php_dom.c
ext/dom/tests/domobject_debug_handler.phpt [new file with mode: 0644]

index 52c778a8344fc283241b0e562f16e713cf1b4c25..e65f58c92509602b8603b1c7990285b22daad8b2 100644 (file)
@@ -468,58 +468,76 @@ static int dom_property_exists(zval *object, zval *member, int check_empty TSRML
 
 static HashTable* dom_get_debug_info_helper(zval *object, int *is_temp TSRMLS_DC) /* {{{ */
 {
-    dom_object *obj = (dom_object *)zend_object_store_get_object(object TSRMLS_CC);
-    HashTable *debug_info, *props;
-    HashPosition pos;
-    dom_prop_handler *entry;
+       dom_object                      *obj = zend_object_store_get_object(object TSRMLS_CC);
+       HashTable                       *debug_info,
+                                               *prop_handlers = obj->prop_handler,
+                                               *std_props;
+       HashPosition            pos;
+       dom_prop_handler        *entry;
+       zval                            *object_value,
+                                               *null_value;
+
+       *is_temp = 1;
+
+       ALLOC_HASHTABLE(debug_info);
+       ZEND_INIT_SYMTABLE_EX(debug_info, 32, 0);
+
+       std_props = zend_std_get_properties(object TSRMLS_CC);
+       zend_hash_copy(debug_info, std_props, (copy_ctor_func_t)zval_add_ref,
+                       NULL, sizeof(zval*));
+
+       if (!prop_handlers) {
+               return debug_info;
+       }
 
-    *is_temp = 1;
+       ALLOC_INIT_ZVAL(object_value);
+       ZVAL_STRING(object_value, "(object value omitted)", 1);
 
-    ALLOC_HASHTABLE(debug_info);
-    if (! obj->prop_handler) {
-        return debug_info;
-    }
+       ALLOC_INIT_ZVAL(null_value);
+       ZVAL_NULL(null_value);
 
-    props = obj->prop_handler;
-    ZEND_INIT_SYMTABLE_EX(debug_info, zend_hash_num_elements(props) + 1, 0);
-
-    zend_hash_internal_pointer_reset_ex(props, &pos);
-    while (zend_hash_get_current_data_ex(props, (void **)&entry, &pos) == SUCCESS) {
-        zval member;
-        zval *value;
-
-        char *string_key=NULL;
-        uint string_length=0;
-        ulong num_key;
-
-        zend_hash_get_current_key_ex(props, &string_key, &string_length, &num_key, 0, &pos);
-
-        INIT_ZVAL(member);
-        ZVAL_STRINGL(&member, string_key, string_length, 0);
-        value = zend_read_property(Z_OBJCE_P(object), object, Z_STRVAL(member), Z_STRLEN(member)-1, 1 TSRMLS_CC);
-        if (value != EG(uninitialized_zval_ptr)) {
-            switch(Z_TYPE_P(value)) {
-                case IS_STRING:
-                case IS_BOOL:
-                case IS_LONG:
-                case IS_DOUBLE:
-                case IS_ARRAY:
-                    zend_hash_add(debug_info, string_key, string_length, &value, sizeof(zval *), NULL);
-                    break;
-
-                default:
-                    ZVAL_NULL(value);
-                    zend_hash_add(debug_info, string_key, string_length, &value, sizeof(zval *), NULL);
-                    break;
-            }
-        } else {
-            ZVAL_NULL(value);
-            zend_hash_add(debug_info, string_key, string_length, &value, sizeof(zval *), NULL);
-        }
-        zend_hash_move_forward_ex(props, &pos);
-    }
+       for (zend_hash_internal_pointer_reset_ex(prop_handlers, &pos);
+                       zend_hash_get_current_data_ex(prop_handlers, (void **)&entry, &pos)
+                                       == SUCCESS;
+                       zend_hash_move_forward_ex(prop_handlers, &pos)) {
+               zval    *value;
+               char    *string_key             = NULL;
+               uint    string_length   = 0;
+               ulong   num_key;
+
+               if (entry->read_func(obj, &value TSRMLS_CC) == FAILURE) {
+                       continue;
+               }
+
+               if (zend_hash_get_current_key_ex(prop_handlers, &string_key,
+                       &string_length, &num_key, 0, &pos) != HASH_KEY_IS_STRING) {
+                       continue;
+               }
+
+               if (value == EG(uninitialized_zval_ptr)) {
+                       value = null_value;
+               } else if (Z_TYPE_P(value) == IS_OBJECT) {
+                       /* these are zvalues create on demand, with refcount and is_ref
+                        * status left in an uninitalized stated */
+                       zval_dtor(value);
+                       efree(value);
+
+                       value = object_value;
+               } else {
+                       /* see comment above */
+                       Z_SET_REFCOUNT_P(value, 0);
+                       Z_UNSET_ISREF_P(value);
+               }
+
+               zval_add_ref(&value);
+               zend_hash_add(debug_info, string_key, string_length,
+                               &value, sizeof(zval *), NULL);
+       }
+
+       zval_ptr_dtor(&null_value);
+       zval_ptr_dtor(&object_value);
 
-    return debug_info;
+       return debug_info;
 }
 /* }}} */
 
diff --git a/ext/dom/tests/domobject_debug_handler.phpt b/ext/dom/tests/domobject_debug_handler.phpt
new file mode 100644 (file)
index 0000000..3c9f133
--- /dev/null
@@ -0,0 +1,59 @@
+--TEST--
+Objects of DOM extension: debug info object handler.
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+$xml = <<<XML
+<foo>
+       <bar>foobar</bar>
+</foo>
+XML;
+$d = new domdocument;
+$d->dynamicProperty = new stdclass;
+$d->loadXML($xml);
+print_r($d);
+--EXPECTF--
+DOMDocument Object
+(
+    [dynamicProperty] => stdClass Object
+        (
+        )
+
+    [doctype] => 
+    [implementation] => (object value omitted)
+    [documentElement] => (object value omitted)
+    [actualEncoding] => 
+    [encoding] => 
+    [xmlEncoding] => 
+    [standalone] => 1
+    [xmlStandalone] => 1
+    [version] => 1.0
+    [xmlVersion] => 1.0
+    [strictErrorChecking] => 1
+    [documentURI] => %s
+    [config] => 
+    [formatOutput] => 
+    [validateOnParse] => 
+    [resolveExternals] => 
+    [preserveWhiteSpace] => 1
+    [recover] => 
+    [substituteEntities] => 
+    [nodeName] => #document
+    [nodeValue] => 
+    [nodeType] => 9
+    [parentNode] => 
+    [childNodes] => (object value omitted)
+    [firstChild] => (object value omitted)
+    [lastChild] => (object value omitted)
+    [previousSibling] => 
+    [attributes] => 
+    [ownerDocument] => 
+    [namespaceURI] => 
+    [prefix] => 
+    [localName] => 
+    [baseURI] => %s
+    [textContent] => 
+       foobar
+
+)