Skip to content

Commit 3ae3341

Browse files
committed
Fixed bug #71018 (ReflectionProperty::setValue() behavior changed)
1 parent 5b9267c commit 3ae3341

File tree

4 files changed

+53
-23
lines changed

4 files changed

+53
-23
lines changed

NEWS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ PHP NEWS
5151
. Fixed stderr being written to stdout. (Bob)
5252

5353
- Reflection:
54+
. Fixed bug #71018 (ReflectionProperty::setValue() behavior changed).
55+
(Laruence)
5456
. Fixed bug #70982 (setStaticPropertyValue behaviors inconsistently with
5557
5.6). (Laruence)
5658

ext/reflection/php_reflection.c

Lines changed: 7 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -5448,31 +5448,16 @@ ZEND_METHOD(reflection_property, setValue)
54485448
}
54495449
variable_ptr = &CE_STATIC_MEMBERS(intern->ce)[ref->prop.offset];
54505450
if (variable_ptr != value) {
5451-
if (Z_ISREF_P(variable_ptr)) {
5452-
zval garbage;
5451+
zval garbage;
54535452

5454-
ZVAL_COPY_VALUE(&garbage, variable_ptr); /* old value should be destroyed */
5453+
ZVAL_DEREF(variable_ptr);
5454+
ZVAL_DEREF(value);
54555455

5456-
/* To check: can't *variable_ptr be some system variable like error_zval here? */
5457-
ZVAL_COPY_VALUE(variable_ptr, value);
5458-
if (Z_REFCOUNTED_P(value) && Z_REFCOUNT_P(value) > 0) {
5459-
zval_copy_ctor(variable_ptr);
5460-
}
5461-
zval_dtor(&garbage);
5462-
} else {
5463-
zval garbage;
5456+
ZVAL_COPY_VALUE(&garbage, variable_ptr);
54645457

5465-
ZVAL_COPY_VALUE(&garbage, variable_ptr);
5466-
/* if we assign referenced variable, we should separate it */
5467-
if (Z_REFCOUNTED_P(value)) {
5468-
Z_ADDREF_P(value);
5469-
}
5470-
if (Z_ISREF_P(value)) {
5471-
SEPARATE_ZVAL(value);
5472-
}
5473-
ZVAL_COPY_VALUE(variable_ptr, value);
5474-
zval_ptr_dtor(&garbage);
5475-
}
5458+
ZVAL_COPY(variable_ptr, value);
5459+
5460+
zval_ptr_dtor(&garbage);
54765461
}
54775462
} else {
54785463
const char *class_name, *prop_name;

ext/reflection/tests/ReflectionProperty_setAccessible.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ string(44) "Cannot access non-public member B::protected"
132132
string(50) "Cannot access non-public member B::protectedStatic"
133133
string(42) "Cannot access non-public member A::private"
134134
string(1) "a"
135-
string(1) "b"
135+
string(1) "f"
136136
string(1) "c"
137137
string(1) "e"
138138
string(1) "f"

ext/reflection/tests/bug71018.phpt

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
--TEST--
2+
Bug #71018 (ReflectionProperty::setValue() behavior changed)
3+
--FILE--
4+
<?php
5+
class T1 {
6+
public static $data;
7+
8+
public static function getDataBySelf()
9+
{
10+
return self::$data;
11+
}
12+
13+
public static function getDataByStatic()
14+
{
15+
return static::$data;
16+
}
17+
}
18+
19+
class T2 extends T1 {}
20+
21+
$Prop1 = new ReflectionProperty(T1::class, 'data');
22+
$Prop2 = new ReflectionProperty(T2::class, 'data');
23+
24+
// #1
25+
// prints: hello, hello in PHP5, but world, hello in PHP7 - not OK
26+
$Prop1->setValue(\T1::class, "world");
27+
$Prop2->setValue(\T2::class, 'hello');
28+
var_dump("T2::self = " . T2::getDataBySelf());
29+
var_dump("T2::static = " . T2::getDataByStatic());
30+
31+
// #2
32+
// prints: hello, hello in both PHP5 and PHP7 - OK
33+
T1::$data = "world";
34+
T2::$data = 'hello';
35+
36+
var_dump("T2::self = " . T2::getDataBySelf());
37+
var_dump("T2::static = " . T2::getDataByStatic());
38+
?>
39+
--EXPECT--
40+
string(16) "T2::self = hello"
41+
string(18) "T2::static = hello"
42+
string(16) "T2::self = hello"
43+
string(18) "T2::static = hello"

0 commit comments

Comments
 (0)