Skip to content

Commit 55e7000

Browse files
DanielEScherzeriluuu1994
authored andcommitted
Reflection: show the type of object constants used as default properties
When a property default is based on a global constant, show the type of the default. Previously, `format_default_value()` assumed that non-scalar and non-array defaults were always going to be `IS_CONSTANT_AST` pointers, and when the AST expression had been evaluated and produced an object, depending on when the `ReflectionClass` or `ReflectionProperty` instance had been created, the default was shown as one of `callable`, `__CLASS__`, or `...`. Instead, if the default value is an object (`IS_OBJECT`), show the type of that object. Add test cases for each of the `callable`, `__CLASS__`, and `...` cases to confirm that they all now properly show the type of the constant. Closes gh-15902
1 parent 41af933 commit 55e7000

File tree

6 files changed

+126
-5
lines changed

6 files changed

+126
-5
lines changed

NEWS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,10 @@ PHP NEWS
5757
- PHPDBG:
5858
. Fixed bug GH-16174 (Empty string is an invalid expression for ev). (cmb)
5959

60+
- Reflection:
61+
. Fixed bug GH-15902 (Core dumped in ext/reflection/php_reflection.c).
62+
(DanielEScherzer)
63+
6064
- Session:
6165
. Fixed bug GH-16385 (Unexpected null returned by session_set_cookie_params).
6266
(nielsdos)

ext/reflection/php_reflection.c

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -639,13 +639,19 @@ static int format_default_value(smart_str *str, zval *value) {
639639
} ZEND_HASH_FOREACH_END();
640640
smart_str_appendc(str, ']');
641641
} else if (Z_TYPE_P(value) == IS_OBJECT) {
642-
/* This branch may only be reached for default properties, which don't support arbitrary objects. */
642+
/* This branch may only be reached for default properties; show enum names,
643+
or the type of non-enums (GH-15902) */
643644
zend_object *obj = Z_OBJ_P(value);
644645
zend_class_entry *class = obj->ce;
645-
ZEND_ASSERT(class->ce_flags & ZEND_ACC_ENUM);
646-
smart_str_append(str, class->name);
647-
smart_str_appends(str, "::");
648-
smart_str_append(str, Z_STR_P(zend_enum_fetch_case_name(obj)));
646+
if (class->ce_flags & ZEND_ACC_ENUM) {
647+
smart_str_append(str, class->name);
648+
smart_str_appends(str, "::");
649+
smart_str_append(str, Z_STR_P(zend_enum_fetch_case_name(obj)));
650+
} else {
651+
smart_str_appends(str, "object(");
652+
smart_str_append(str, class->name);
653+
smart_str_appends(str, ")");
654+
}
649655
} else {
650656
ZEND_ASSERT(Z_TYPE_P(value) == IS_CONSTANT_AST);
651657
zend_string *ast_str = zend_ast_export("", Z_ASTVAL_P(value), "");
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
--TEST--
2+
ReflectionClass object default property - used to say "callable"
3+
--FILE--
4+
<?php
5+
6+
class C {
7+
public stdClass $a = FOO;
8+
}
9+
define('FOO', new stdClass);
10+
11+
new C;
12+
13+
$reflector = new ReflectionClass(C::class);
14+
var_dump( (string)$reflector );
15+
?>
16+
--EXPECTF--
17+
string(%d) "Class [ <user> class C ] {
18+
@@ %sReflectionClass-callable.php %d-%d
19+
20+
- Constants [0] {
21+
}
22+
23+
- Static properties [0] {
24+
}
25+
26+
- Static methods [0] {
27+
}
28+
29+
- Properties [1] {
30+
Property [ public stdClass $a = object(stdClass) ]
31+
}
32+
33+
- Methods [0] {
34+
}
35+
}
36+
"
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
--TEST--
2+
ReflectionClass object default property - used to say "__CLASS__"
3+
--FILE--
4+
<?php
5+
6+
class C {
7+
public stdClass $a = FOO;
8+
}
9+
$reflector = new ReflectionClass(C::class);
10+
11+
define('FOO', new stdClass);
12+
new C;
13+
14+
var_dump( (string)$reflector );
15+
16+
?>
17+
--EXPECTF--
18+
string(%d) "Class [ <user> class C ] {
19+
@@ %sReflectionClass-class.php %d-%d
20+
21+
- Constants [0] {
22+
}
23+
24+
- Static properties [0] {
25+
}
26+
27+
- Static methods [0] {
28+
}
29+
30+
- Properties [1] {
31+
Property [ public stdClass $a = object(stdClass) ]
32+
}
33+
34+
- Methods [0] {
35+
}
36+
}
37+
"
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
--TEST--
2+
ReflectionProperty object default - used to say "callable"
3+
--FILE--
4+
<?php
5+
6+
class C {
7+
public stdClass $a = FOO;
8+
}
9+
define('FOO', new stdClass);
10+
11+
new C;
12+
13+
$reflector = new ReflectionProperty(C::class, 'a');
14+
var_dump( (string)$reflector );
15+
16+
?>
17+
--EXPECTF--
18+
string(%d) "Property [ public stdClass $a = object(stdClass) ]
19+
"
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
--TEST--
2+
ReflectionProperty object default - used to say "__CLASS__"
3+
--FILE--
4+
<?php
5+
6+
class C {
7+
public stdClass $a = FOO;
8+
}
9+
$reflector = new ReflectionProperty(C::class, 'a');
10+
11+
define('FOO', new stdClass);
12+
new C;
13+
14+
var_dump( (string)$reflector );
15+
16+
?>
17+
--EXPECTF--
18+
string(%d) "Property [ public stdClass $a = object(stdClass) ]
19+
"

0 commit comments

Comments
 (0)