Skip to content

Commit

Permalink
Merge branch 'xdebug_3_4'
Browse files Browse the repository at this point in the history
  • Loading branch information
derickr committed Jan 22, 2025
2 parents 75dc3da + f9363d6 commit 63ab243
Show file tree
Hide file tree
Showing 6 changed files with 230 additions and 6 deletions.
12 changes: 11 additions & 1 deletion src/lib/var.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| Xdebug |
+----------------------------------------------------------------------+
| Copyright (c) 2002-2023 Derick Rethans |
| Copyright (c) 2002-2025 Derick Rethans |
+----------------------------------------------------------------------+
| This source file is subject to version 1.01 of the Xdebug license, |
| that is bundled with this package in the file LICENSE, and is |
Expand Down Expand Up @@ -501,6 +501,12 @@ static void fetch_zval_from_symbol_table(
/* As a normal (public) property */
zval *tmp = zend_symtable_str_find(myht, name, name_length);
if (tmp != NULL) {
#if PHP_VERSION_ID >= 80400
if (Z_TYPE_P(tmp) == IS_PTR) {
zend_release_properties(myht);
goto skip_for_property_hook;
}
#endif
ZVAL_COPY(&tmp_retval, tmp);
zend_release_properties(myht);
goto cleanup;
Expand All @@ -522,6 +528,10 @@ static void fetch_zval_from_symbol_table(
zend_release_properties(myht);
}
}

#if PHP_VERSION_ID >= 80400
skip_for_property_hook:
#endif
/* First we try an object handler */
if (cce) {
zval *tmp_val;
Expand Down
50 changes: 45 additions & 5 deletions src/lib/var_export_xml.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| Xdebug |
+----------------------------------------------------------------------+
| Copyright (c) 2002-2024 Derick Rethans |
| Copyright (c) 2002-2025 Derick Rethans |
+----------------------------------------------------------------------+
| This source file is subject to version 1.01 of the Xdebug license, |
| that is bundled with this package in the file LICENSE, and is |
Expand Down Expand Up @@ -141,6 +141,7 @@ typedef struct
int name_len;
unsigned long index_key;
zval *zv;
zend_object *zobj;
} xdebug_object_item;

static void merged_hash_object_item_dtor(zval *data)
Expand All @@ -150,14 +151,15 @@ static void merged_hash_object_item_dtor(zval *data)
xdfree(item);
}

static int object_item_add_to_merged_hash(zval *zv_nptr, zend_ulong index_key, zend_string *hash_key, HashTable *merged, int object_type)
static int object_item_add_to_merged_hash(zval *zv_nptr, zend_ulong index_key, zend_string *hash_key, HashTable *merged, int object_type, zend_object *zobj)
{
zval **zv = &zv_nptr;
xdebug_object_item *item;

item = xdcalloc(1, sizeof(xdebug_object_item));
item->type = object_type;
item->zv = *zv;
item->zobj = zobj;

if (hash_key) {
item->name = (char*) HASH_APPLY_KEY_VAL(hash_key);
Expand All @@ -173,7 +175,7 @@ static int object_item_add_to_merged_hash(zval *zv_nptr, zend_ulong index_key, z
return 0;
}

static int object_item_add_zend_prop_to_merged_hash(zend_property_info *zpp, HashTable *merged, int object_type, zend_class_entry *ce)
static int object_item_add_zend_prop_to_merged_hash(zend_property_info *zpp, HashTable *merged, int object_type, zend_object *zobj, zend_class_entry *ce)
{
xdebug_object_item *item;

Expand All @@ -184,6 +186,7 @@ static int object_item_add_zend_prop_to_merged_hash(zend_property_info *zpp, Has
item = xdmalloc(sizeof(xdebug_object_item));
item->type = object_type;
item->zv = &CE_STATIC_MEMBERS(ce)[zpp->offset];
item->zobj = zobj;
item->name = (char*) STR_NAME_VAL(zpp->name);
item->name_len = STR_NAME_LEN(zpp->name);

Expand Down Expand Up @@ -406,7 +409,44 @@ static int xdebug_object_element_export_xml_node(xdebug_object_item *item_nptr,
}

xdebug_xml_add_child(parent, node);

#if PHP_VERSION_ID >= 80400
{
zval tmp_for_is_ptr;
zval *tmp_value_for_ptr = NULL;

if (Z_TYPE_P((*item)->zv) == IS_PTR) {
// IS_PTR is for properties with hooks
zend_property_info *prop_info = Z_PTR_P((*item)->zv);
const char *unmangled_name_cstr;
zend_string *unmangled_name;

if ((prop_info->flags & ZEND_ACC_VIRTUAL) && !prop_info->hooks[ZEND_PROPERTY_HOOK_GET]) {
return 0;
}

unmangled_name_cstr = zend_get_unmangled_property_name(prop_info->name);
unmangled_name = zend_string_init(unmangled_name_cstr, strlen(unmangled_name_cstr), false);

tmp_value_for_ptr = zend_read_property_ex(prop_info->ce, (*item)->zobj, unmangled_name, /* silent */ true, &tmp_for_is_ptr);

zend_string_release_ex(unmangled_name, false);
if (EG(exception)) {
return 0;
}

xdebug_var_export_xml_node(&tmp_value_for_ptr, tmp_fullname ? tmp_fullname : NULL, node, options, level + 1);

if (tmp_value_for_ptr == &tmp_for_is_ptr) {
zval_ptr_dtor(tmp_value_for_ptr);
}
} else {
xdebug_var_export_xml_node(&((*item)->zv), tmp_fullname ? tmp_fullname : NULL, node, options, level + 1);
}
}
#else
xdebug_var_export_xml_node(&((*item)->zv), tmp_fullname ? tmp_fullname : NULL, node, options, level + 1);
#endif

if (tmp_name) {
xdebug_str_free(tmp_name);
Expand Down Expand Up @@ -606,7 +646,7 @@ void xdebug_var_export_xml_node(zval **struc, xdebug_str *name, xdebug_xml_node
#endif

ZEND_HASH_FOREACH_PTR(&ce->properties_info, zpi_val) {
object_item_add_zend_prop_to_merged_hash(zpi_val, merged_hash, (int) XDEBUG_OBJECT_ITEM_TYPE_STATIC_PROPERTY, ce);
object_item_add_zend_prop_to_merged_hash(zpi_val, merged_hash, (int) XDEBUG_OBJECT_ITEM_TYPE_STATIC_PROPERTY, Z_OBJ_P(*struc), ce);
} ZEND_HASH_FOREACH_END();

xdebug_zend_hash_apply_protection_end(&ce->properties_info);
Expand Down Expand Up @@ -641,7 +681,7 @@ void xdebug_var_export_xml_node(zval **struc, xdebug_str *name, xdebug_xml_node
}
}
#endif
object_item_add_to_merged_hash(tmp_val, num, key, merged_hash, flags);
object_item_add_to_merged_hash(tmp_val, num, key, merged_hash, flags, Z_OBJ_P(*struc));
} ZEND_HASH_FOREACH_END();

xdebug_zend_hash_apply_protection_end(myht);
Expand Down
33 changes: 33 additions & 0 deletions tests/debugger/bug02314-001.inc
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php
class Foo
{
public string $time_string {
get {
return $this->date->format('H:i:s');
}
}

public function __construct(
public DateTime $date = new DateTime('1979-01-01 00:00:00') {
set (string|DateTime $value) {
if (is_string($value)) {
$this->date = new DateTime($value);
} else {
$this->date = $value;
}
}
}
)
{
}
}

$date = new DateTime('1980-01-01 00:00:00' );

$foo = new Foo();
var_dump($foo->date);
$foo->date = '1970-01-01 12:34:56';
var_dump($foo->date);
echo $foo->time_string;
echo '';
?>
55 changes: 55 additions & 0 deletions tests/debugger/bug02314-001.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
--TEST--
Test for bug #2314: Class properties with hooks are always shown as null [1]
--SKIPIF--
<?php
require __DIR__ . '/../utils.inc';
check_reqs('PHP >= 8.4; dbgp');
?>
--FILE--
<?php
require 'dbgp/dbgpclient.php';
$filename = dirname(__FILE__) . '/bug02314-001.inc';

$commands = array(
'step_into',
'breakpoint_set -t line -n 30',
'run',
'context_get -c 0',
'property_get -c 0 -n $foo',
'property_get -c 0 -n $foo->date',
'detach',
);

dbgpRunFile( $filename, $commands );
?>
--EXPECTF--
<?xml version="1.0" encoding="iso-8859-1"?>
<init xmlns="urn:debugger_protocol_v1" xmlns:xdebug="https://xdebug.org/dbgp/xdebug" fileuri="file://bug02314-001.inc" language="PHP" xdebug:language_version="" protocol_version="1.0" appid=""><engine version=""><![CDATA[Xdebug]]></engine><author><![CDATA[Derick Rethans]]></author><url><![CDATA[https://xdebug.org]]></url><copyright><![CDATA[Copyright (c) 2002-2099 by Derick Rethans]]></copyright></init>

-> step_into -i 1
<?xml version="1.0" encoding="iso-8859-1"?>
<response xmlns="urn:debugger_protocol_v1" xmlns:xdebug="https://xdebug.org/dbgp/xdebug" command="step_into" transaction_id="1" status="break" reason="ok"><xdebug:message filename="file://bug02314-001.inc" lineno="%d"></xdebug:message></response>

-> breakpoint_set -i 2 -t line -n 30
<?xml version="1.0" encoding="iso-8859-1"?>
<response xmlns="urn:debugger_protocol_v1" xmlns:xdebug="https://xdebug.org/dbgp/xdebug" command="breakpoint_set" transaction_id="2" id="{{PID}}0001"></response>

-> run -i 3
<?xml version="1.0" encoding="iso-8859-1"?>
<response xmlns="urn:debugger_protocol_v1" xmlns:xdebug="https://xdebug.org/dbgp/xdebug" command="run" transaction_id="3" status="break" reason="ok"><xdebug:message filename="file://bug02314-001.inc" lineno="30"></xdebug:message></response>

-> context_get -i 4 -c 0
<?xml version="1.0" encoding="iso-8859-1"?>
<response xmlns="urn:debugger_protocol_v1" xmlns:xdebug="https://xdebug.org/dbgp/xdebug" command="context_get" transaction_id="4" context="0"><property name="$date" fullname="$date" type="object" classname="DateTime" children="1" numchildren="3" page="0" pagesize="32"><property name="date" fullname="$date-&gt;date" facet="public" type="string" size="26" encoding="base64"><![CDATA[MTk4MC0wMS0wMSAwMDowMDowMC4wMDAwMDA=]]></property><property name="timezone_type" fullname="$date-&gt;timezone_type" facet="public" type="int"><![CDATA[3]]></property><property name="timezone" fullname="$date-&gt;timezone" facet="public" type="string" size="3" encoding="base64"><![CDATA[VVRD]]></property></property><property name="$foo" fullname="$foo" type="object" classname="Foo" children="1" numchildren="2" page="0" pagesize="32"><property name="time_string" fullname="$foo-&gt;time_string" facet="public" type="string" size="8" encoding="base64"><![CDATA[MTI6MzQ6NTY=]]></property><property name="date" fullname="$foo-&gt;date" facet="public" type="object" classname="DateTime" children="1" numchildren="3"></property></property></response>

-> property_get -i 5 -c 0 -n $foo
<?xml version="1.0" encoding="iso-8859-1"?>
<response xmlns="urn:debugger_protocol_v1" xmlns:xdebug="https://xdebug.org/dbgp/xdebug" command="property_get" transaction_id="5"><property name="$foo" fullname="$foo" type="object" classname="Foo" children="1" numchildren="2" page="0" pagesize="32"><property name="time_string" fullname="$foo-&gt;time_string" facet="public" type="string" size="8" encoding="base64"><![CDATA[MTI6MzQ6NTY=]]></property><property name="date" fullname="$foo-&gt;date" facet="public" type="object" classname="DateTime" children="1" numchildren="3"></property></property></response>

-> property_get -i 6 -c 0 -n $foo->date
<?xml version="1.0" encoding="iso-8859-1"?>
<response xmlns="urn:debugger_protocol_v1" xmlns:xdebug="https://xdebug.org/dbgp/xdebug" command="property_get" transaction_id="6"><property name="$foo-&gt;date" fullname="$foo-&gt;date" type="object" classname="DateTime" children="1" numchildren="3" page="0" pagesize="32"><property name="date" fullname="$foo-&gt;date-&gt;date" facet="public" type="string" size="26" encoding="base64"><![CDATA[MTk3MC0wMS0wMSAxMjozNDo1Ni4wMDAwMDA=]]></property><property name="timezone_type" fullname="$foo-&gt;date-&gt;timezone_type" facet="public" type="int"><![CDATA[3]]></property><property name="timezone" fullname="$foo-&gt;date-&gt;timezone" facet="public" type="string" size="3" encoding="base64"><![CDATA[VVRD]]></property></property></response>

-> detach -i 7
<?xml version="1.0" encoding="iso-8859-1"?>
<response xmlns="urn:debugger_protocol_v1" xmlns:xdebug="https://xdebug.org/dbgp/xdebug" command="detach" transaction_id="7" status="stopping" reason="ok"></response>
36 changes: 36 additions & 0 deletions tests/debugger/bug02314-002.inc
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?php
class Foo
{
public string $time_string {
get {
return $this->date->format('H:i:s');
}
}

public function __construct(
private DateTime $date = new DateTime('1979-01-01 00:00:00') {
set (string|DateTime $value) {
if (is_string($value)) {
$this->date = new DateTime($value);
} else {
$this->date = $value;
}
}
}
)
{
}

function setNewDate( string|DateTime $date )
{
$this->date = $date;
}
}

$date = new DateTime('1980-01-01 00:00:00' );

$foo = new Foo();
$foo->setNewDate( '1970-01-01 12:34:56' );
echo $foo->time_string;
echo '';
?>
50 changes: 50 additions & 0 deletions tests/debugger/bug02314-002.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
--TEST--
Test for bug #2314: Class properties with hooks are always shown as null [2]
--SKIPIF--
<?php
require __DIR__ . '/../utils.inc';
check_reqs('PHP >= 8.4; dbgp');
?>
--FILE--
<?php
require 'dbgp/dbgpclient.php';
$filename = dirname(__FILE__) . '/bug02314-002.inc';

$commands = array(
'step_into',
'breakpoint_set -t line -n 34',
'run',
'context_get -c 0',
'property_get -c 0 -n $foo->date',
'detach',
);

dbgpRunFile( $filename, $commands );
?>
--EXPECTF--
<?xml version="1.0" encoding="iso-8859-1"?>
<init xmlns="urn:debugger_protocol_v1" xmlns:xdebug="https://xdebug.org/dbgp/xdebug" fileuri="file://bug02314-002.inc" language="PHP" xdebug:language_version="" protocol_version="1.0" appid=""><engine version=""><![CDATA[Xdebug]]></engine><author><![CDATA[Derick Rethans]]></author><url><![CDATA[https://xdebug.org]]></url><copyright><![CDATA[Copyright (c) 2002-2099 by Derick Rethans]]></copyright></init>

-> step_into -i 1
<?xml version="1.0" encoding="iso-8859-1"?>
<response xmlns="urn:debugger_protocol_v1" xmlns:xdebug="https://xdebug.org/dbgp/xdebug" command="step_into" transaction_id="1" status="break" reason="ok"><xdebug:message filename="file://bug02314-002.inc" lineno="%d"></xdebug:message></response>

-> breakpoint_set -i 2 -t line -n 34
<?xml version="1.0" encoding="iso-8859-1"?>
<response xmlns="urn:debugger_protocol_v1" xmlns:xdebug="https://xdebug.org/dbgp/xdebug" command="breakpoint_set" transaction_id="2" id="{{PID}}0001"></response>

-> run -i 3
<?xml version="1.0" encoding="iso-8859-1"?>
<response xmlns="urn:debugger_protocol_v1" xmlns:xdebug="https://xdebug.org/dbgp/xdebug" command="run" transaction_id="3" status="break" reason="ok"><xdebug:message filename="file://bug02314-002.inc" lineno="34"></xdebug:message></response>

-> context_get -i 4 -c 0
<?xml version="1.0" encoding="iso-8859-1"?>
<response xmlns="urn:debugger_protocol_v1" xmlns:xdebug="https://xdebug.org/dbgp/xdebug" command="context_get" transaction_id="4" context="0"><property name="$date" fullname="$date" type="object" classname="DateTime" children="1" numchildren="3" page="0" pagesize="32"><property name="date" fullname="$date-&gt;date" facet="public" type="string" size="26" encoding="base64"><![CDATA[MTk4MC0wMS0wMSAwMDowMDowMC4wMDAwMDA=]]></property><property name="timezone_type" fullname="$date-&gt;timezone_type" facet="public" type="int"><![CDATA[3]]></property><property name="timezone" fullname="$date-&gt;timezone" facet="public" type="string" size="3" encoding="base64"><![CDATA[VVRD]]></property></property><property name="$foo" fullname="$foo" type="object" classname="Foo" children="1" numchildren="2" page="0" pagesize="32"><property name="time_string" fullname="$foo-&gt;time_string" facet="public" type="string" size="8" encoding="base64"><![CDATA[MTI6MzQ6NTY=]]></property><property name="date" fullname="$foo-&gt;date" facet="private" type="object" classname="DateTime" children="1" numchildren="3"></property></property></response>

-> property_get -i 5 -c 0 -n $foo->date
<?xml version="1.0" encoding="iso-8859-1"?>
<response xmlns="urn:debugger_protocol_v1" xmlns:xdebug="https://xdebug.org/dbgp/xdebug" command="property_get" transaction_id="5"><property name="$foo-&gt;date" fullname="$foo-&gt;date" type="object" classname="DateTime" children="1" numchildren="3" page="0" pagesize="32"><property name="date" fullname="$foo-&gt;date-&gt;date" facet="public" type="string" size="26" encoding="base64"><![CDATA[MTk3MC0wMS0wMSAxMjozNDo1Ni4wMDAwMDA=]]></property><property name="timezone_type" fullname="$foo-&gt;date-&gt;timezone_type" facet="public" type="int"><![CDATA[3]]></property><property name="timezone" fullname="$foo-&gt;date-&gt;timezone" facet="public" type="string" size="3" encoding="base64"><![CDATA[VVRD]]></property></property></response>

-> detach -i 6
<?xml version="1.0" encoding="iso-8859-1"?>
<response xmlns="urn:debugger_protocol_v1" xmlns:xdebug="https://xdebug.org/dbgp/xdebug" command="detach" transaction_id="6" status="stopping" reason="ok"></response>

0 comments on commit 63ab243

Please sign in to comment.