summaryrefslogtreecommitdiff
path: root/ext/dom
diff options
context:
space:
mode:
authorGustavo André dos Santos Lopes <cataphract@php.net>2012-03-22 21:49:04 (GMT)
committerGustavo André dos Santos Lopes <cataphract@php.net>2012-03-23 21:23:24 (GMT)
commitb61017c9b635f4ab00582e073f7c17894be88980 (patch)
treecdd7d730bbbd235b3518527dcce8adee8b70c539 /ext/dom
parentd04682766d66da083d9b14400bd9c75dd9b1463b (diff)
downloadphp-b61017c9b635f4ab00582e073f7c17894be88980.tar.gz
Improved on DOM object debug info handler. Added test.
Diffstat (limited to 'ext/dom')
-rw-r--r--ext/dom/php_dom.c114
-rw-r--r--ext/dom/tests/domobject_debug_handler.phpt59
2 files changed, 125 insertions, 48 deletions
diff --git a/ext/dom/php_dom.c b/ext/dom/php_dom.c
index 52c778a..e65f58c 100644
--- a/ext/dom/php_dom.c
+++ b/ext/dom/php_dom.c
@@ -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
index 0000000..3c9f133
--- /dev/null
+++ b/ext/dom/tests/domobject_debug_handler.phpt
@@ -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
+
+)