summaryrefslogtreecommitdiff
path: root/ext/standard
diff options
context:
space:
mode:
authorNikita Popov <nikita.ppv@gmail.com>2021-03-03 16:28:39 +0100
committerNikita Popov <nikita.ppv@gmail.com>2021-03-04 10:11:37 +0100
commit500b4b4945e3768afd2cfcae61548ef47e7f003f (patch)
tree5ccaa3fa9563789e054713a1a927945b5a6c9ea3 /ext/standard
parent4b59071844d4749e05a73d3d21527c7875e831f8 (diff)
downloadphp-git-500b4b4945e3768afd2cfcae61548ef47e7f003f.tar.gz
Explicitly print reference wrappers in debug_zval_dump()
Closes GH-6750.
Diffstat (limited to 'ext/standard')
-rw-r--r--ext/standard/tests/general_functions/debug_zval_dump_o.phpt42
-rw-r--r--ext/standard/tests/general_functions/debug_zval_dump_refs.phpt46
-rw-r--r--ext/standard/var.c35
3 files changed, 86 insertions, 37 deletions
diff --git a/ext/standard/tests/general_functions/debug_zval_dump_o.phpt b/ext/standard/tests/general_functions/debug_zval_dump_o.phpt
index e248bdc8be..89ed4a63d2 100644
--- a/ext/standard/tests/general_functions/debug_zval_dump_o.phpt
+++ b/ext/standard/tests/general_functions/debug_zval_dump_o.phpt
@@ -345,26 +345,30 @@ object(object_class)#%d (7) refcount(%d){
["object_class1"]=>
*RECURSION*
["obj"]=>
- &object(object_class)#%d (7) refcount(%d){
- ["value1"]=>
- int(5)
- ["value2":"object_class":private]=>
- int(10)
- ["value3":protected]=>
- int(20)
- ["value4"]=>
- int(30)
- ["array_var"]=>
- array(2) refcount(%d){
- ["key1"]=>
- int(1)
- ["key2 "]=>
- int(3)
+ reference refcount(2) {
+ object(object_class)#8 (7) refcount(2){
+ ["value1"]=>
+ int(5)
+ ["value2":"object_class":private]=>
+ int(10)
+ ["value3":protected]=>
+ int(20)
+ ["value4"]=>
+ int(30)
+ ["array_var"]=>
+ array(2) refcount(7){
+ ["key1"]=>
+ int(1)
+ ["key2 "]=>
+ int(3)
+ }
+ ["object_class1"]=>
+ *RECURSION*
+ ["obj"]=>
+ reference refcount(2) {
+ *RECURSION*
+ }
}
- ["object_class1"]=>
- *RECURSION*
- ["obj"]=>
- *RECURSION*
}
}
Done
diff --git a/ext/standard/tests/general_functions/debug_zval_dump_refs.phpt b/ext/standard/tests/general_functions/debug_zval_dump_refs.phpt
new file mode 100644
index 0000000000..0af30d3379
--- /dev/null
+++ b/ext/standard/tests/general_functions/debug_zval_dump_refs.phpt
@@ -0,0 +1,46 @@
+--TEST--
+References in debug_zval_dump()
+--FILE--
+<?php
+
+$r = 1;
+$a = [&$r];
+debug_zval_dump($a);
+$a[] =& $r;
+debug_zval_dump($a);
+unset($a[1]);
+debug_zval_dump($a);
+unset($r);
+// rc=1 singleton ref remains
+debug_zval_dump($a);
+
+?>
+--EXPECT--
+array(1) refcount(2){
+ [0]=>
+ reference refcount(2) {
+ int(1)
+ }
+}
+array(2) refcount(2){
+ [0]=>
+ reference refcount(3) {
+ int(1)
+ }
+ [1]=>
+ reference refcount(3) {
+ int(1)
+ }
+}
+array(1) refcount(2){
+ [0]=>
+ reference refcount(2) {
+ int(1)
+ }
+}
+array(1) refcount(2){
+ [0]=>
+ reference refcount(1) {
+ int(1)
+ }
+}
diff --git a/ext/standard/var.c b/ext/standard/var.c
index d4c99495d1..06b98b5b9d 100644
--- a/ext/standard/var.c
+++ b/ext/standard/var.c
@@ -269,7 +269,6 @@ PHPAPI void php_debug_zval_dump(zval *struc, int level) /* {{{ */
{
HashTable *myht = NULL;
zend_string *class_name;
- int is_ref = 0;
zend_ulong index;
zend_string *key;
zval *val;
@@ -279,25 +278,24 @@ PHPAPI void php_debug_zval_dump(zval *struc, int level) /* {{{ */
php_printf("%*c", level - 1, ' ');
}
-again:
switch (Z_TYPE_P(struc)) {
case IS_FALSE:
- php_printf("%sbool(false)\n", COMMON);
+ PUTS("bool(false)\n");
break;
case IS_TRUE:
- php_printf("%sbool(true)\n", COMMON);
+ PUTS("bool(true)\n");
break;
case IS_NULL:
- php_printf("%sNULL\n", COMMON);
+ PUTS("NULL\n");
break;
case IS_LONG:
- php_printf("%sint(" ZEND_LONG_FMT ")\n", COMMON, Z_LVAL_P(struc));
+ php_printf("int(" ZEND_LONG_FMT ")\n", Z_LVAL_P(struc));
break;
case IS_DOUBLE:
- php_printf_unchecked("%sfloat(%.*H)\n", COMMON, (int) PG(serialize_precision), Z_DVAL_P(struc));
+ php_printf_unchecked("float(%.*H)\n", (int) PG(serialize_precision), Z_DVAL_P(struc));
break;
case IS_STRING:
- php_printf("%sstring(%zd) \"", COMMON, Z_STRLEN_P(struc));
+ php_printf("string(%zd) \"", Z_STRLEN_P(struc));
PHPWRITE(Z_STRVAL_P(struc), Z_STRLEN_P(struc));
if (Z_REFCOUNTED_P(struc)) {
php_printf("\" refcount(%u)\n", Z_REFCOUNT_P(struc));
@@ -318,9 +316,9 @@ again:
count = zend_hash_num_elements(myht);
if (Z_REFCOUNTED_P(struc)) {
/* -1 because of ADDREF above. */
- php_printf("%sarray(%d) refcount(%u){\n", COMMON, count, Z_REFCOUNT_P(struc) - 1);
+ php_printf("array(%d) refcount(%u){\n", count, Z_REFCOUNT_P(struc) - 1);
} else {
- php_printf("%sarray(%d) interned {\n", COMMON, count);
+ php_printf("array(%d) interned {\n", count);
}
ZEND_HASH_FOREACH_KEY_VAL(myht, index, key, val) {
zval_array_element_dump(val, index, key, level);
@@ -345,7 +343,7 @@ again:
GC_PROTECT_RECURSION(myht);
}
class_name = Z_OBJ_HANDLER_P(struc, get_class_name)(Z_OBJ_P(struc));
- php_printf("%sobject(%s)#%d (%d) refcount(%u){\n", COMMON, ZSTR_VAL(class_name), Z_OBJ_HANDLE_P(struc), myht ? zend_array_count(myht) : 0, Z_REFCOUNT_P(struc));
+ php_printf("object(%s)#%d (%d) refcount(%u){\n", ZSTR_VAL(class_name), Z_OBJ_HANDLE_P(struc), myht ? zend_array_count(myht) : 0, Z_REFCOUNT_P(struc));
zend_string_release_ex(class_name, 0);
if (myht) {
ZEND_HASH_FOREACH_KEY_VAL(myht, index, key, val) {
@@ -372,18 +370,19 @@ again:
break;
case IS_RESOURCE: {
const char *type_name = zend_rsrc_list_get_rsrc_type(Z_RES_P(struc));
- php_printf("%sresource(%d) of type (%s) refcount(%u)\n", COMMON, Z_RES_P(struc)->handle, type_name ? type_name : "Unknown", Z_REFCOUNT_P(struc));
+ php_printf("resource(%d) of type (%s) refcount(%u)\n", Z_RES_P(struc)->handle, type_name ? type_name : "Unknown", Z_REFCOUNT_P(struc));
break;
}
case IS_REFERENCE:
- //??? hide references with refcount==1 (for compatibility)
- if (Z_REFCOUNT_P(struc) > 1) {
- is_ref = 1;
+ php_printf("reference refcount(%u) {\n", Z_REFCOUNT_P(struc));
+ php_debug_zval_dump(Z_REFVAL_P(struc), level + 2);
+ if (level > 1) {
+ php_printf("%*c", level - 1, ' ');
}
- struc = Z_REFVAL_P(struc);
- goto again;
+ PUTS("}\n");
+ break;
default:
- php_printf("%sUNKNOWN:0\n", COMMON);
+ PUTS("UNKNOWN:0\n");
break;
}
}