Skip to content

Commit db7ead0

Browse files
committed
Fix ReflectionProperty::get/setValue() on internal static property
This was broken by 6dc0cd8, which moved static property initialization outside of constant updating. Instead of replicating logic, use zend_get_static_property() API in the reflection implementation, just like we're using read_property for non-static proprety access.
1 parent e1e0176 commit db7ead0

File tree

2 files changed

+38
-31
lines changed

2 files changed

+38
-31
lines changed

ext/reflection/php_reflection.c

Lines changed: 22 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -5495,18 +5495,16 @@ ZEND_METHOD(reflection_property, getValue)
54955495
return;
54965496
}
54975497

5498-
if ((ref->prop.flags & ZEND_ACC_STATIC)) {
5499-
if (UNEXPECTED(zend_update_class_constants(intern->ce) != SUCCESS)) {
5500-
return;
5501-
}
5502-
if (Z_TYPE(CE_STATIC_MEMBERS(intern->ce)[ref->prop.offset]) == IS_UNDEF) {
5503-
zend_throw_error(NULL, "Internal error: Could not find the property %s::%s", ZSTR_VAL(intern->ce->name), ZSTR_VAL(ref->prop.name));
5504-
return;
5498+
if (ref->prop.flags & ZEND_ACC_STATIC) {
5499+
zend_class_entry *old_scope = EG(fake_scope);
5500+
EG(fake_scope) = ref->ce;
5501+
member_p = zend_std_get_static_property(ref->ce, ref->unmangled_name, 0);
5502+
EG(fake_scope) = old_scope;
5503+
5504+
if (member_p) {
5505+
ZVAL_DEREF(member_p);
5506+
ZVAL_COPY(return_value, member_p);
55055507
}
5506-
member_p = &CE_STATIC_MEMBERS(intern->ce)[ref->prop.offset];
5507-
ZVAL_DEINDIRECT(member_p);
5508-
ZVAL_DEREF(member_p);
5509-
ZVAL_COPY(return_value, member_p);
55105508
} else {
55115509
zval rv;
55125510

@@ -5554,34 +5552,27 @@ ZEND_METHOD(reflection_property, setValue)
55545552
return;
55555553
}
55565554

5557-
if ((ref->prop.flags & ZEND_ACC_STATIC)) {
5555+
if (ref->prop.flags & ZEND_ACC_STATIC) {
5556+
zend_class_entry *old_scope;
5557+
zval garbage;
5558+
55585559
if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(), "z", &value) == FAILURE) {
55595560
if (zend_parse_parameters(ZEND_NUM_ARGS(), "zz", &tmp, &value) == FAILURE) {
55605561
return;
55615562
}
55625563
}
5563-
if (UNEXPECTED(zend_update_class_constants(intern->ce) != SUCCESS)) {
5564-
return;
5565-
}
55665564

5567-
if (Z_TYPE(CE_STATIC_MEMBERS(intern->ce)[ref->prop.offset]) == IS_UNDEF) {
5568-
zend_throw_error(NULL, "Internal error: Could not find the property %s::%s", ZSTR_VAL(intern->ce->name), ZSTR_VAL(ref->prop.name));
5569-
return;
5570-
}
5571-
variable_ptr = &CE_STATIC_MEMBERS(intern->ce)[ref->prop.offset];
5572-
ZVAL_DEINDIRECT(variable_ptr);
5573-
if (variable_ptr != value) {
5574-
zval garbage;
5565+
old_scope = EG(fake_scope);
5566+
EG(fake_scope) = ref->ce;
5567+
variable_ptr = zend_std_get_static_property(ref->ce, ref->unmangled_name, 0);
5568+
EG(fake_scope) = old_scope;
55755569

5576-
ZVAL_DEREF(variable_ptr);
5577-
ZVAL_DEREF(value);
5570+
ZVAL_DEREF(variable_ptr);
5571+
ZVAL_DEREF(value);
55785572

5579-
ZVAL_COPY_VALUE(&garbage, variable_ptr);
5580-
5581-
ZVAL_COPY(variable_ptr, value);
5582-
5583-
zval_ptr_dtor(&garbage);
5584-
}
5573+
ZVAL_COPY_VALUE(&garbage, variable_ptr);
5574+
ZVAL_COPY(variable_ptr, value);
5575+
zval_ptr_dtor(&garbage);
55855576
} else {
55865577
if (zend_parse_parameters(ZEND_NUM_ARGS(), "oz", &object, &value) == FAILURE) {
55875578
return;
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
--TEST--
2+
ReflectionProperty::get/setValue() on internal static property
3+
--SKIPIF--
4+
<?php
5+
if (!class_exists('_ZendTestClass')) die('skip zend_test extension required');
6+
?>
7+
--FILE--
8+
<?php
9+
10+
$rp = new ReflectionProperty('_ZendTestClass', '_StaticProp');
11+
$rp->setValue(42);
12+
var_dump($rp->getValue());
13+
14+
?>
15+
--EXPECT--
16+
int(42)

0 commit comments

Comments
 (0)