Skip to content

Commit 56b2b9f

Browse files
committed
Fix GH-21687: assertion failure in zend_enum_fetch_case_name after array_walk
array_walk() wraps object properties in IS_REFERENCE when passing them to the callback. For enum objects, this converts the name property from IS_STRING to IS_REFERENCE in-place. A subsequent var_dump() calls zend_enum_fetch_case_name() which asserts IS_STRING on the property, triggering an assertion failure. Dereference through IS_REFERENCE in both zend_enum_fetch_case_name() and zend_enum_fetch_case_value() before accessing the value. Closes GH-21687
1 parent dc7f6a8 commit 56b2b9f

2 files changed

Lines changed: 23 additions & 1 deletion

File tree

Zend/tests/gh21687.phpt

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
--TEST--
2+
GH-21687 (Assertion failure in zend_enum_fetch_case_name after array_walk on enum)
3+
--FILE--
4+
<?php
5+
enum Foo: int {
6+
case Bar = 0;
7+
}
8+
9+
$bar = Foo::Bar;
10+
array_walk($bar, function($v) {});
11+
var_dump($bar);
12+
echo $bar->name . "\n";
13+
echo $bar->value . "\n";
14+
?>
15+
--EXPECT--
16+
enum(Foo::Bar)
17+
Bar
18+
0

Zend/zend_enum.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ static zend_always_inline zval *zend_enum_fetch_case_name(zend_object *zobj)
6969
ZEND_ASSERT(zobj->ce->ce_flags & ZEND_ACC_ENUM);
7070

7171
zval *name = OBJ_PROP_NUM(zobj, 0);
72+
ZVAL_DEREF(name);
7273
ZEND_ASSERT(Z_TYPE_P(name) == IS_STRING);
7374
return name;
7475
}
@@ -77,7 +78,10 @@ static zend_always_inline zval *zend_enum_fetch_case_value(zend_object *zobj)
7778
{
7879
ZEND_ASSERT(zobj->ce->ce_flags & ZEND_ACC_ENUM);
7980
ZEND_ASSERT(zobj->ce->enum_backing_type != IS_UNDEF);
80-
return OBJ_PROP_NUM(zobj, 1);
81+
82+
zval *value = OBJ_PROP_NUM(zobj, 1);
83+
ZVAL_DEREF(value);
84+
return value;
8185
}
8286

8387
END_EXTERN_C()

0 commit comments

Comments
 (0)