Skip to content
Permalink
Browse files

Fixed issue #1724: Missing property types and uninitialised values in…

… variable dumping routines
  • Loading branch information
derickr committed Dec 6, 2019
1 parent a70029e commit 4ebbe4d5be5842e98425c23cd657d96937d32964
@@ -924,6 +924,41 @@ void xdebug_dump_used_var_with_contents(void *htmlq, xdebug_hash_element* he, vo
zval_ptr_dtor_nogc(&zvar);
}

#if PHP_VERSION_ID >= 70400
xdebug_str* xdebug_get_property_type(zval* object, zval *val)
{
xdebug_str *type_str = NULL;
zend_property_info *info;

if (Z_TYPE_P(val) != IS_INDIRECT) {
return NULL;
}
val = Z_INDIRECT_P(val);

info = zend_get_typed_property_info_for_slot(Z_OBJ_P(object), val);

if (info) {
type_str = xdebug_str_new();

if (ZEND_TYPE_ALLOW_NULL(info->type)) {
xdebug_str_addc(type_str, '?');
}
if (ZEND_TYPE_IS_CLASS(info->type)) {
xdebug_str_add(
type_str,
ZSTR_VAL(
ZEND_TYPE_IS_CE(info->type) ? ZEND_TYPE_CE(info->type)->name : ZEND_TYPE_NAME(info->type)
),
0
);
} else {
xdebug_str_add(type_str, zend_get_type_by_const(ZEND_TYPE_CODE(info->type)), 0);
}
}

return type_str;
}
#endif

xdebug_str* xdebug_get_property_info(char *mangled_property, int mangled_len, const char **modifier, char **class_name)
{
@@ -65,6 +65,9 @@ void xdebug_get_php_symbol(zval *retval, xdebug_str* name);
xdebug_var_export_options* xdebug_var_export_options_from_ini(void);
xdebug_var_export_options* xdebug_var_get_nolimit_options(void);

#if PHP_VERSION_ID >= 70400
xdebug_str* xdebug_get_property_type(zval* object, zval *val);
#endif
xdebug_str* xdebug_get_property_info(char *mangled_property, int mangled_len, const char **modifier, char **class_name);
HashTable *xdebug_objdebug_pp(zval **zval_pp, int *is_tmp);
void xdebug_var_maybe_destroy_ht(HashTable *ht, int is_temp);
@@ -65,7 +65,7 @@ static int xdebug_array_element_export_html(zval *zv_nptr, zend_ulong index_key,
return 0;
}

static int xdebug_object_element_export_html(zval *zv_nptr, zend_ulong index_key, zend_string *hash_key, int level, xdebug_str *str, int debug_zval, xdebug_var_export_options *options, char *class_name)
static int xdebug_object_element_export_html(zval *object, zval *zv_nptr, zend_ulong index_key, zend_string *hash_key, int level, xdebug_str *str, int debug_zval, xdebug_var_export_options *options, char *class_name)
{
zval **zv = &zv_nptr;

@@ -77,18 +77,29 @@ static int xdebug_object_element_export_html(zval *zv_nptr, zend_ulong index_key
if (!HASH_KEY_IS_NUMERIC(hash_key)) {
char *prop_class_name;
xdebug_str *property_name;
xdebug_str *property_type = NULL;
const char *modifier;

#if PHP_VERSION_ID >= 70400
property_type = xdebug_get_property_type(object, zv_nptr);
#endif
property_name = xdebug_get_property_info((char*) HASH_APPLY_KEY_VAL(hash_key), HASH_APPLY_KEY_LEN(hash_key), &modifier, &prop_class_name);

xdebug_str_add(str, xdebug_sprintf("<i>%s</i> '", modifier), 1);
xdebug_str_add(str, xdebug_sprintf("<i>%s</i> ", modifier), 1);
if (property_type) {
xdebug_str_add(str, xdebug_sprintf("<i>%s</i> ", property_type->d), 1);
}
xdebug_str_addc(str, '\'');
xdebug_str_add_str(str, property_name);
if (strcmp(modifier, "private") != 0 || strcmp(class_name, prop_class_name) == 0) {
xdebug_str_add(str, xdebug_sprintf("' <font color='%s'>=&gt;</font> ", COLOR_POINTER), 1);
} else {
xdebug_str_add(str, xdebug_sprintf("' <small>(%s)</small> <font color='%s'>=&gt;</font> ", prop_class_name, COLOR_POINTER), 1);
}

if (property_type) {
xdebug_str_free(property_type);
}
xdebug_str_free(property_name);
xdfree(prop_class_name);
} else {
@@ -118,6 +129,10 @@ void xdebug_var_export_html(zval **struc, xdebug_str *str, int level, int debug_
if (debug_zval) {
xdebug_add_variable_attributes(str, *struc, XDEBUG_VAR_ATTR_HTML);
}
if (Z_TYPE_P(*struc) == IS_INDIRECT) {
tmpz = Z_INDIRECT_P(*struc);
struc = &tmpz;
}
if (Z_TYPE_P(*struc) == IS_REFERENCE) {
tmpz = &((*struc)->value.ref->val);
struc = &tmpz;
@@ -204,8 +219,8 @@ void xdebug_var_export_html(zval **struc, xdebug_str *str, int level, int debug_

xdebug_zend_hash_apply_protection_begin(myht);

ZEND_HASH_FOREACH_KEY_VAL_IND(myht, num, key, val) {
xdebug_object_element_export_html(val, num, key, level, str, debug_zval, options, class_name);
ZEND_HASH_FOREACH_KEY_VAL(myht, num, key, val) {
xdebug_object_element_export_html(*struc, val, num, key, level, str, debug_zval, options, class_name);
} ZEND_HASH_FOREACH_END();

xdebug_zend_hash_apply_protection_end(myht);
@@ -58,7 +58,7 @@ static int xdebug_array_element_export(zval *zv_nptr, zend_ulong index_key, zend
return 0;
}

static int xdebug_object_element_export(zval *zv_nptr, zend_ulong index_key, zend_string *hash_key, int level, xdebug_str *str, int debug_zval, xdebug_var_export_options *options, char *class_name)
static int xdebug_object_element_export(zval *object, zval *zv_nptr, zend_ulong index_key, zend_string *hash_key, int level, xdebug_str *str, int debug_zval, xdebug_var_export_options *options, char *class_name)
{
zval **zv = &zv_nptr;

@@ -67,11 +67,19 @@ static int xdebug_object_element_export(zval *zv_nptr, zend_ulong index_key, zen
{
if (!HASH_KEY_IS_NUMERIC(hash_key)) {
xdebug_str *property_name;
xdebug_str *property_type = NULL;
char *prop_class_name;
const char *modifier;

#if PHP_VERSION_ID >= 70400
property_type = xdebug_get_property_type(object, zv_nptr);
#endif
property_name = xdebug_get_property_info((char*) HASH_APPLY_KEY_VAL(hash_key), HASH_APPLY_KEY_LEN(hash_key), &modifier, &prop_class_name);
xdebug_str_add(str, modifier, 0);
if (property_type) {
xdebug_str_addc(str, ' ');
xdebug_str_add_str(str, property_type);
}
xdebug_str_addl(str, " $", 2, 0);
if (strcmp(modifier, "private") != 0 || strcmp(class_name, prop_class_name) == 0) {
xdebug_str_add_str(str, property_name);
@@ -84,6 +92,9 @@ static int xdebug_object_element_export(zval *zv_nptr, zend_ulong index_key, zen
xdebug_str_addl(str, " = ", 3, 0);
}

if (property_type) {
xdebug_str_free(property_type);
}
xdebug_str_free(property_name);
xdfree(prop_class_name);
} else {
@@ -116,6 +127,10 @@ void xdebug_var_export_line(zval **struc, xdebug_str *str, int level, int debug_
if (debug_zval) {
xdebug_add_variable_attributes(str, *struc, XDEBUG_VAR_ATTR_TEXT);
}
if (Z_TYPE_P(*struc) == IS_INDIRECT) {
tmpz = Z_INDIRECT_P(*struc);
struc = &tmpz;
}
if (Z_TYPE_P(*struc) == IS_REFERENCE) {
tmpz = &((*struc)->value.ref->val);
struc = &tmpz;
@@ -210,8 +225,8 @@ void xdebug_var_export_line(zval **struc, xdebug_str *str, int level, int debug_

xdebug_zend_hash_apply_protection_begin(myht);

ZEND_HASH_FOREACH_KEY_VAL_IND(myht, num, key, val) {
xdebug_object_element_export(val, num, key, level, str, debug_zval, options, class_name);
ZEND_HASH_FOREACH_KEY_VAL(myht, num, key, val) {
xdebug_object_element_export(*struc, val, num, key, level, str, debug_zval, options, class_name);
} ZEND_HASH_FOREACH_END();

xdebug_zend_hash_apply_protection_end(myht);
@@ -85,7 +85,7 @@ static int xdebug_array_element_export_text_ansi(zval *zv_nptr, zend_ulong index
return 0;
}

static int xdebug_object_element_export_text_ansi(zval *zv_nptr, zend_ulong index_key, zend_string *hash_key, int level, int mode, xdebug_str *str, int debug_zval, xdebug_var_export_options *options)
static int xdebug_object_element_export_text_ansi(zval *object, zval *zv_nptr, zend_ulong index_key, zend_string *hash_key, int level, int mode, xdebug_str *str, int debug_zval, xdebug_var_export_options *options)
{
zval **zv = &zv_nptr;

@@ -98,14 +98,22 @@ static int xdebug_object_element_export_text_ansi(zval *zv_nptr, zend_ulong inde
char *class_name;
xdebug_str *property_name;
const char *modifier;
xdebug_str *property_type = NULL;

#if PHP_VERSION_ID >= 70400
property_type = xdebug_get_property_type(object, zv_nptr);
#endif

property_name = xdebug_get_property_info((char*) HASH_APPLY_KEY_VAL(hash_key), HASH_APPLY_KEY_LEN(hash_key), &modifier, &class_name);
xdebug_str_add(str, xdebug_sprintf("%s%s%s%s%s $",
ANSI_COLOR_MODIFIER, ANSI_COLOR_BOLD, modifier, ANSI_COLOR_BOLD_OFF, ANSI_COLOR_RESET), 1);
xdebug_str_add(str, xdebug_sprintf("%s%s%s%s%s%s%s $",
ANSI_COLOR_MODIFIER, ANSI_COLOR_BOLD, modifier, ANSI_COLOR_BOLD_OFF, property_type ? " " : "", property_type ? property_type->d : "", ANSI_COLOR_RESET), 1);
xdebug_str_add_str(str, property_name);
xdebug_str_add(str, xdebug_sprintf(" %s=>%s\n",
ANSI_COLOR_POINTER, ANSI_COLOR_RESET), 1);

if (property_type) {
xdebug_str_free(property_type);
}
xdebug_str_free(property_name);
xdfree(class_name);
} else {
@@ -142,6 +150,10 @@ static void xdebug_var_export_text_ansi(zval **struc, xdebug_str *str, int mode,
if (debug_zval) {
xdebug_add_variable_attributes(str, *struc, XDEBUG_VAR_ATTR_TEXT);
}
if (Z_TYPE_P(*struc) == IS_INDIRECT) {
tmpz = Z_INDIRECT_P(*struc);
struc = &tmpz;
}
if (Z_TYPE_P(*struc) == IS_REFERENCE) {
tmpz = &((*struc)->value.ref->val);
struc = &tmpz;
@@ -243,8 +255,8 @@ static void xdebug_var_export_text_ansi(zval **struc, xdebug_str *str, int mode,

xdebug_zend_hash_apply_protection_begin(myht);

ZEND_HASH_FOREACH_KEY_VAL_IND(myht, num, key, val) {
xdebug_object_element_export_text_ansi(val, num, key, level, mode, str, debug_zval, options);
ZEND_HASH_FOREACH_KEY_VAL(myht, num, key, val) {
xdebug_object_element_export_text_ansi(*struc, val, num, key, level, mode, str, debug_zval, options);
} ZEND_HASH_FOREACH_END();

xdebug_zend_hash_apply_protection_end(myht);
@@ -0,0 +1,56 @@
--TEST--
xdebug_var_dump() with typed properties [ansi]
--SKIPIF--
<?php
require __DIR__ . '/../utils.inc';
check_reqs('PHP >= 7.4');
?>
--INI--
xdebug.default_enable=1
xdebug.auto_trace=0
xdebug.profiler_enable=0
html_errors=0
xdebug.var_display_max_children=11
xdebug.overload_var_dump=2
xdebug.cli_color=2
xdebug.file_link_format=
xdebug.filename_format=
--FILE--
<?php
class foo {
public $v = M_PI;
public $w;
private string $x;
protected int $y = 42;
public ?Fibble $z;
public \DateTime $a;
}

$f = new foo;
$f->a = new \DateTime;

var_dump($f);
var_dump(new class{public string $x;});
?>
--EXPECTF--
%sxdebug_var_dump_typed_properties-ansi.php:14:
class foo#1 (6) {
public $v =>
double(3.1415926535898)
public $w =>
NULL
private string $x =>
*uninitialized*
protected int $y =>
int(42)
public ?Fibble $z =>
*uninitialized*
public DateTime $a =>
class DateTime#2 (0) {
}
}
%sxdebug_var_dump_typed_properties-ansi.php:15:
class class@anonymous#3 (1) {
public string $x =>
*uninitialized*
}
@@ -0,0 +1,49 @@
--TEST--
xdebug_var_dump() with typed properties [html]
--SKIPIF--
<?php
require __DIR__ . '/../utils.inc';
check_reqs('PHP >= 7.4');
?>
--INI--
xdebug.default_enable=1
xdebug.auto_trace=0
xdebug.profiler_enable=0
html_errors=1
xdebug.var_display_max_children=11
xdebug.overload_var_dump=2
xdebug.file_link_format=
xdebug.filename_format=
--FILE--
<?php
class foo {
public $v = M_PI;
public $w;
private string $x;
protected int $y = 42;
public ?Fibble $z;
public \DateTime $a;
}

$f = new foo;
$f->a = new \DateTime;

var_dump($f);
var_dump(new class{public string $x;});
?>
--EXPECTF--
<pre class='xdebug-var-dump' dir='ltr'>
<small>%sxdebug_var_dump_typed_properties-html.php:14:</small>
<b>object</b>(<i>foo</i>)[<i>1</i>]
<i>public</i> 'v' <font color='#888a85'>=&gt;</font> <small>float</small> <font color='#f57900'>3.1415926535898</font>
<i>public</i> 'w' <font color='#888a85'>=&gt;</font> <font color='#3465a4'>null</font>
<i>private</i> <i>string</i> 'x' <font color='#888a85'>=&gt;</font> <font color='#3465a4'>*uninitialized*</font>
<i>protected</i> <i>int</i> 'y' <font color='#888a85'>=&gt;</font> <small>int</small> <font color='#4e9a06'>42</font>
<i>public</i> <i>?Fibble</i> 'z' <font color='#888a85'>=&gt;</font> <font color='#3465a4'>*uninitialized*</font>
<i>public</i> <i>DateTime</i> 'a' <font color='#888a85'>=&gt;</font>
<b>object</b>(<i>DateTime</i>)[<i>2</i>]
</pre><pre class='xdebug-var-dump' dir='ltr'>
<small>%sxdebug_var_dump_typed_properties-html.php:15:</small>
<b>object</b>(<i>class@anonymous</i>)[<i>3</i>]
<i>public</i> <i>string</i> 'x' <font color='#888a85'>=&gt;</font> <font color='#3465a4'>*uninitialized*</font>
</pre>
@@ -0,0 +1,56 @@
--TEST--
xdebug_var_dump() with typed properties [text]
--SKIPIF--
<?php
require __DIR__ . '/../utils.inc';
check_reqs('PHP >= 7.4');
?>
--INI--
xdebug.default_enable=1
xdebug.auto_trace=0
xdebug.profiler_enable=0
html_errors=0
xdebug.var_display_max_children=11
xdebug.overload_var_dump=2
xdebug.cli_color=0
xdebug.file_link_format=
xdebug.filename_format=
--FILE--
<?php
class foo {
public $v = M_PI;
public $w;
private string $x;
protected int $y = 42;
public ?Fibble $z;
public \DateTime $a;
}

$f = new foo;
$f->a = new \DateTime;

var_dump($f);
var_dump(new class{public string $x;});
?>
--EXPECTF--
%sxdebug_var_dump_typed_properties-text.php:14:
class foo#1 (6) {
public $v =>
double(3.1415926535898)
public $w =>
NULL
private string $x =>
*uninitialized*
protected int $y =>
int(42)
public ?Fibble $z =>
*uninitialized*
public DateTime $a =>
class DateTime#2 (0) {
}
}
%sxdebug_var_dump_typed_properties-text.php:15:
class class@anonymous#3 (1) {
public string $x =>
*uninitialized*
}

0 comments on commit 4ebbe4d

Please sign in to comment.
You can’t perform that action at this time.