Skip to content

Commit 63ab243

Browse files
committed
Merge branch 'xdebug_3_4'
2 parents 75dc3da + f9363d6 commit 63ab243

File tree

6 files changed

+230
-6
lines changed

6 files changed

+230
-6
lines changed

src/lib/var.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
+----------------------------------------------------------------------+
33
| Xdebug |
44
+----------------------------------------------------------------------+
5-
| Copyright (c) 2002-2023 Derick Rethans |
5+
| Copyright (c) 2002-2025 Derick Rethans |
66
+----------------------------------------------------------------------+
77
| This source file is subject to version 1.01 of the Xdebug license, |
88
| that is bundled with this package in the file LICENSE, and is |
@@ -501,6 +501,12 @@ static void fetch_zval_from_symbol_table(
501501
/* As a normal (public) property */
502502
zval *tmp = zend_symtable_str_find(myht, name, name_length);
503503
if (tmp != NULL) {
504+
#if PHP_VERSION_ID >= 80400
505+
if (Z_TYPE_P(tmp) == IS_PTR) {
506+
zend_release_properties(myht);
507+
goto skip_for_property_hook;
508+
}
509+
#endif
504510
ZVAL_COPY(&tmp_retval, tmp);
505511
zend_release_properties(myht);
506512
goto cleanup;
@@ -522,6 +528,10 @@ static void fetch_zval_from_symbol_table(
522528
zend_release_properties(myht);
523529
}
524530
}
531+
532+
#if PHP_VERSION_ID >= 80400
533+
skip_for_property_hook:
534+
#endif
525535
/* First we try an object handler */
526536
if (cce) {
527537
zval *tmp_val;

src/lib/var_export_xml.c

Lines changed: 45 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
+----------------------------------------------------------------------+
33
| Xdebug |
44
+----------------------------------------------------------------------+
5-
| Copyright (c) 2002-2024 Derick Rethans |
5+
| Copyright (c) 2002-2025 Derick Rethans |
66
+----------------------------------------------------------------------+
77
| This source file is subject to version 1.01 of the Xdebug license, |
88
| that is bundled with this package in the file LICENSE, and is |
@@ -141,6 +141,7 @@ typedef struct
141141
int name_len;
142142
unsigned long index_key;
143143
zval *zv;
144+
zend_object *zobj;
144145
} xdebug_object_item;
145146

146147
static void merged_hash_object_item_dtor(zval *data)
@@ -150,14 +151,15 @@ static void merged_hash_object_item_dtor(zval *data)
150151
xdfree(item);
151152
}
152153

153-
static int object_item_add_to_merged_hash(zval *zv_nptr, zend_ulong index_key, zend_string *hash_key, HashTable *merged, int object_type)
154+
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)
154155
{
155156
zval **zv = &zv_nptr;
156157
xdebug_object_item *item;
157158

158159
item = xdcalloc(1, sizeof(xdebug_object_item));
159160
item->type = object_type;
160161
item->zv = *zv;
162+
item->zobj = zobj;
161163

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

176-
static int object_item_add_zend_prop_to_merged_hash(zend_property_info *zpp, HashTable *merged, int object_type, zend_class_entry *ce)
178+
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)
177179
{
178180
xdebug_object_item *item;
179181

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

@@ -406,7 +409,44 @@ static int xdebug_object_element_export_xml_node(xdebug_object_item *item_nptr,
406409
}
407410

408411
xdebug_xml_add_child(parent, node);
412+
413+
#if PHP_VERSION_ID >= 80400
414+
{
415+
zval tmp_for_is_ptr;
416+
zval *tmp_value_for_ptr = NULL;
417+
418+
if (Z_TYPE_P((*item)->zv) == IS_PTR) {
419+
// IS_PTR is for properties with hooks
420+
zend_property_info *prop_info = Z_PTR_P((*item)->zv);
421+
const char *unmangled_name_cstr;
422+
zend_string *unmangled_name;
423+
424+
if ((prop_info->flags & ZEND_ACC_VIRTUAL) && !prop_info->hooks[ZEND_PROPERTY_HOOK_GET]) {
425+
return 0;
426+
}
427+
428+
unmangled_name_cstr = zend_get_unmangled_property_name(prop_info->name);
429+
unmangled_name = zend_string_init(unmangled_name_cstr, strlen(unmangled_name_cstr), false);
430+
431+
tmp_value_for_ptr = zend_read_property_ex(prop_info->ce, (*item)->zobj, unmangled_name, /* silent */ true, &tmp_for_is_ptr);
432+
433+
zend_string_release_ex(unmangled_name, false);
434+
if (EG(exception)) {
435+
return 0;
436+
}
437+
438+
xdebug_var_export_xml_node(&tmp_value_for_ptr, tmp_fullname ? tmp_fullname : NULL, node, options, level + 1);
439+
440+
if (tmp_value_for_ptr == &tmp_for_is_ptr) {
441+
zval_ptr_dtor(tmp_value_for_ptr);
442+
}
443+
} else {
444+
xdebug_var_export_xml_node(&((*item)->zv), tmp_fullname ? tmp_fullname : NULL, node, options, level + 1);
445+
}
446+
}
447+
#else
409448
xdebug_var_export_xml_node(&((*item)->zv), tmp_fullname ? tmp_fullname : NULL, node, options, level + 1);
449+
#endif
410450

411451
if (tmp_name) {
412452
xdebug_str_free(tmp_name);
@@ -606,7 +646,7 @@ void xdebug_var_export_xml_node(zval **struc, xdebug_str *name, xdebug_xml_node
606646
#endif
607647

608648
ZEND_HASH_FOREACH_PTR(&ce->properties_info, zpi_val) {
609-
object_item_add_zend_prop_to_merged_hash(zpi_val, merged_hash, (int) XDEBUG_OBJECT_ITEM_TYPE_STATIC_PROPERTY, ce);
649+
object_item_add_zend_prop_to_merged_hash(zpi_val, merged_hash, (int) XDEBUG_OBJECT_ITEM_TYPE_STATIC_PROPERTY, Z_OBJ_P(*struc), ce);
610650
} ZEND_HASH_FOREACH_END();
611651

612652
xdebug_zend_hash_apply_protection_end(&ce->properties_info);
@@ -641,7 +681,7 @@ void xdebug_var_export_xml_node(zval **struc, xdebug_str *name, xdebug_xml_node
641681
}
642682
}
643683
#endif
644-
object_item_add_to_merged_hash(tmp_val, num, key, merged_hash, flags);
684+
object_item_add_to_merged_hash(tmp_val, num, key, merged_hash, flags, Z_OBJ_P(*struc));
645685
} ZEND_HASH_FOREACH_END();
646686

647687
xdebug_zend_hash_apply_protection_end(myht);

tests/debugger/bug02314-001.inc

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?php
2+
class Foo
3+
{
4+
public string $time_string {
5+
get {
6+
return $this->date->format('H:i:s');
7+
}
8+
}
9+
10+
public function __construct(
11+
public DateTime $date = new DateTime('1979-01-01 00:00:00') {
12+
set (string|DateTime $value) {
13+
if (is_string($value)) {
14+
$this->date = new DateTime($value);
15+
} else {
16+
$this->date = $value;
17+
}
18+
}
19+
}
20+
)
21+
{
22+
}
23+
}
24+
25+
$date = new DateTime('1980-01-01 00:00:00' );
26+
27+
$foo = new Foo();
28+
var_dump($foo->date);
29+
$foo->date = '1970-01-01 12:34:56';
30+
var_dump($foo->date);
31+
echo $foo->time_string;
32+
echo '';
33+
?>

tests/debugger/bug02314-001.phpt

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
--TEST--
2+
Test for bug #2314: Class properties with hooks are always shown as null [1]
3+
--SKIPIF--
4+
<?php
5+
require __DIR__ . '/../utils.inc';
6+
check_reqs('PHP >= 8.4; dbgp');
7+
?>
8+
--FILE--
9+
<?php
10+
require 'dbgp/dbgpclient.php';
11+
$filename = dirname(__FILE__) . '/bug02314-001.inc';
12+
13+
$commands = array(
14+
'step_into',
15+
'breakpoint_set -t line -n 30',
16+
'run',
17+
'context_get -c 0',
18+
'property_get -c 0 -n $foo',
19+
'property_get -c 0 -n $foo->date',
20+
'detach',
21+
);
22+
23+
dbgpRunFile( $filename, $commands );
24+
?>
25+
--EXPECTF--
26+
<?xml version="1.0" encoding="iso-8859-1"?>
27+
<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>
28+
29+
-> step_into -i 1
30+
<?xml version="1.0" encoding="iso-8859-1"?>
31+
<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>
32+
33+
-> breakpoint_set -i 2 -t line -n 30
34+
<?xml version="1.0" encoding="iso-8859-1"?>
35+
<response xmlns="urn:debugger_protocol_v1" xmlns:xdebug="https://xdebug.org/dbgp/xdebug" command="breakpoint_set" transaction_id="2" id="{{PID}}0001"></response>
36+
37+
-> run -i 3
38+
<?xml version="1.0" encoding="iso-8859-1"?>
39+
<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>
40+
41+
-> context_get -i 4 -c 0
42+
<?xml version="1.0" encoding="iso-8859-1"?>
43+
<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>
44+
45+
-> property_get -i 5 -c 0 -n $foo
46+
<?xml version="1.0" encoding="iso-8859-1"?>
47+
<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>
48+
49+
-> property_get -i 6 -c 0 -n $foo->date
50+
<?xml version="1.0" encoding="iso-8859-1"?>
51+
<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>
52+
53+
-> detach -i 7
54+
<?xml version="1.0" encoding="iso-8859-1"?>
55+
<response xmlns="urn:debugger_protocol_v1" xmlns:xdebug="https://xdebug.org/dbgp/xdebug" command="detach" transaction_id="7" status="stopping" reason="ok"></response>

tests/debugger/bug02314-002.inc

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<?php
2+
class Foo
3+
{
4+
public string $time_string {
5+
get {
6+
return $this->date->format('H:i:s');
7+
}
8+
}
9+
10+
public function __construct(
11+
private DateTime $date = new DateTime('1979-01-01 00:00:00') {
12+
set (string|DateTime $value) {
13+
if (is_string($value)) {
14+
$this->date = new DateTime($value);
15+
} else {
16+
$this->date = $value;
17+
}
18+
}
19+
}
20+
)
21+
{
22+
}
23+
24+
function setNewDate( string|DateTime $date )
25+
{
26+
$this->date = $date;
27+
}
28+
}
29+
30+
$date = new DateTime('1980-01-01 00:00:00' );
31+
32+
$foo = new Foo();
33+
$foo->setNewDate( '1970-01-01 12:34:56' );
34+
echo $foo->time_string;
35+
echo '';
36+
?>

tests/debugger/bug02314-002.phpt

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
--TEST--
2+
Test for bug #2314: Class properties with hooks are always shown as null [2]
3+
--SKIPIF--
4+
<?php
5+
require __DIR__ . '/../utils.inc';
6+
check_reqs('PHP >= 8.4; dbgp');
7+
?>
8+
--FILE--
9+
<?php
10+
require 'dbgp/dbgpclient.php';
11+
$filename = dirname(__FILE__) . '/bug02314-002.inc';
12+
13+
$commands = array(
14+
'step_into',
15+
'breakpoint_set -t line -n 34',
16+
'run',
17+
'context_get -c 0',
18+
'property_get -c 0 -n $foo->date',
19+
'detach',
20+
);
21+
22+
dbgpRunFile( $filename, $commands );
23+
?>
24+
--EXPECTF--
25+
<?xml version="1.0" encoding="iso-8859-1"?>
26+
<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>
27+
28+
-> step_into -i 1
29+
<?xml version="1.0" encoding="iso-8859-1"?>
30+
<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>
31+
32+
-> breakpoint_set -i 2 -t line -n 34
33+
<?xml version="1.0" encoding="iso-8859-1"?>
34+
<response xmlns="urn:debugger_protocol_v1" xmlns:xdebug="https://xdebug.org/dbgp/xdebug" command="breakpoint_set" transaction_id="2" id="{{PID}}0001"></response>
35+
36+
-> run -i 3
37+
<?xml version="1.0" encoding="iso-8859-1"?>
38+
<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>
39+
40+
-> context_get -i 4 -c 0
41+
<?xml version="1.0" encoding="iso-8859-1"?>
42+
<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>
43+
44+
-> property_get -i 5 -c 0 -n $foo->date
45+
<?xml version="1.0" encoding="iso-8859-1"?>
46+
<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>
47+
48+
-> detach -i 6
49+
<?xml version="1.0" encoding="iso-8859-1"?>
50+
<response xmlns="urn:debugger_protocol_v1" xmlns:xdebug="https://xdebug.org/dbgp/xdebug" command="detach" transaction_id="6" status="stopping" reason="ok"></response>

0 commit comments

Comments
 (0)