diff options
author | Xinchen Hui <laruence@gmail.com> | 2015-12-04 11:10:07 +0800 |
---|---|---|
committer | Xinchen Hui <laruence@gmail.com> | 2015-12-04 11:52:08 +0800 |
commit | 3ae3341533b68cccaccfc0d78456b72d004dfc80 (patch) | |
tree | dd737758dc7630ddb8d48d1ac2eeb5f82dcef4ea | |
parent | 5b9267c4c0909b3c3ba27326bda9020d4a1c4470 (diff) | |
download | php-git-3ae3341533b68cccaccfc0d78456b72d004dfc80.tar.gz |
Fixed bug #71018 (ReflectionProperty::setValue() behavior changed)
-rw-r--r-- | NEWS | 2 | ||||
-rw-r--r-- | ext/reflection/php_reflection.c | 29 | ||||
-rw-r--r-- | ext/reflection/tests/ReflectionProperty_setAccessible.phpt | 2 | ||||
-rw-r--r-- | ext/reflection/tests/bug71018.phpt | 43 |
4 files changed, 53 insertions, 23 deletions
@@ -51,6 +51,8 @@ PHP NEWS . Fixed stderr being written to stdout. (Bob) - Reflection: + . Fixed bug #71018 (ReflectionProperty::setValue() behavior changed). + (Laruence) . Fixed bug #70982 (setStaticPropertyValue behaviors inconsistently with 5.6). (Laruence) diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index 72df8b5901..80001e4997 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -5448,31 +5448,16 @@ ZEND_METHOD(reflection_property, setValue) } variable_ptr = &CE_STATIC_MEMBERS(intern->ce)[ref->prop.offset]; if (variable_ptr != value) { - if (Z_ISREF_P(variable_ptr)) { - zval garbage; + zval garbage; - ZVAL_COPY_VALUE(&garbage, variable_ptr); /* old value should be destroyed */ + ZVAL_DEREF(variable_ptr); + ZVAL_DEREF(value); - /* To check: can't *variable_ptr be some system variable like error_zval here? */ - ZVAL_COPY_VALUE(variable_ptr, value); - if (Z_REFCOUNTED_P(value) && Z_REFCOUNT_P(value) > 0) { - zval_copy_ctor(variable_ptr); - } - zval_dtor(&garbage); - } else { - zval garbage; + ZVAL_COPY_VALUE(&garbage, variable_ptr); - ZVAL_COPY_VALUE(&garbage, variable_ptr); - /* if we assign referenced variable, we should separate it */ - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } - if (Z_ISREF_P(value)) { - SEPARATE_ZVAL(value); - } - ZVAL_COPY_VALUE(variable_ptr, value); - zval_ptr_dtor(&garbage); - } + ZVAL_COPY(variable_ptr, value); + + zval_ptr_dtor(&garbage); } } else { const char *class_name, *prop_name; diff --git a/ext/reflection/tests/ReflectionProperty_setAccessible.phpt b/ext/reflection/tests/ReflectionProperty_setAccessible.phpt index 1e829b3a6c..cc184c1920 100644 --- a/ext/reflection/tests/ReflectionProperty_setAccessible.phpt +++ b/ext/reflection/tests/ReflectionProperty_setAccessible.phpt @@ -132,7 +132,7 @@ string(44) "Cannot access non-public member B::protected" string(50) "Cannot access non-public member B::protectedStatic" string(42) "Cannot access non-public member A::private" string(1) "a" -string(1) "b" +string(1) "f" string(1) "c" string(1) "e" string(1) "f" diff --git a/ext/reflection/tests/bug71018.phpt b/ext/reflection/tests/bug71018.phpt new file mode 100644 index 0000000000..00baa31d3c --- /dev/null +++ b/ext/reflection/tests/bug71018.phpt @@ -0,0 +1,43 @@ +--TEST-- +Bug #71018 (ReflectionProperty::setValue() behavior changed) +--FILE-- +<?php +class T1 { + public static $data; + + public static function getDataBySelf() + { + return self::$data; + } + + public static function getDataByStatic() + { + return static::$data; + } +} + +class T2 extends T1 {} + +$Prop1 = new ReflectionProperty(T1::class, 'data'); +$Prop2 = new ReflectionProperty(T2::class, 'data'); + +// #1 +// prints: hello, hello in PHP5, but world, hello in PHP7 - not OK +$Prop1->setValue(\T1::class, "world"); +$Prop2->setValue(\T2::class, 'hello'); +var_dump("T2::self = " . T2::getDataBySelf()); +var_dump("T2::static = " . T2::getDataByStatic()); + +// #2 +// prints: hello, hello in both PHP5 and PHP7 - OK +T1::$data = "world"; +T2::$data = 'hello'; + +var_dump("T2::self = " . T2::getDataBySelf()); +var_dump("T2::static = " . T2::getDataByStatic()); +?> +--EXPECT-- +string(16) "T2::self = hello" +string(18) "T2::static = hello" +string(16) "T2::self = hello" +string(18) "T2::static = hello" |