From: Gustavo André dos Santos Lopes <cataphract@php.net> Date: Thu, 22 Mar 2012 21:49:04 +0000 (+0000) Subject: Improved on DOM object debug info handler. Added test. X-Git-Tag: php-5.4.1RC1~40^2^2~2 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=b61017c9b635f4ab00582e073f7c17894be88980;p=php Improved on DOM object debug info handler. Added test. --- diff --git a/ext/dom/php_dom.c b/ext/dom/php_dom.c index 52c778a834..e65f58c925 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 0000000000..3c9f133548 --- /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 + +)