com php-src: Re-Fixed bug #70321 (Magic getter breaks reference to array property): NEWS Zend/tests/bug70321.phpt Zend/zend_execute. c
| From: | Xinchen Hui | Date: | Sun, 23 Aug 2015 03:42:33 +0000 |
| Subject: | com php-src: Re-Fixed bug #70321 (Magic getter breaks reference to array property): NEWS Zend/tests/bug70321.phpt Zend/zend_execute. c | ||
| Groups: | php.cvs | ||
| Request: | Send a blank email to php-cvs+get-88727@lists.php.net to get a copy of this message | ||
Commit: 55f88141c5a308ae507ef23606b190387e6c37dc
Author: Xinchen Hui <laruence@php.net> Sun, 23 Aug 2015 11:40:49 +0800
Parents: e26a04f9ecb18fe6d233fb5840f71ad216f27938
Branches: master
Link: http://git.php.net/?p=php-src.git;a=commitdiff;h=55f88141c5a308ae507ef23606b190387e6c37dc
Log:
Re-Fixed bug #70321 (Magic getter breaks reference to array property)
Bugs:
https://bugs.php.net/70321
Changed paths:
M NEWS
A Zend/tests/bug70321.phpt
M Zend/zend_execute.c
Diff:
diff --git a/NEWS b/NEWS
index f92f283..d401f5f 100644
--- a/NEWS
+++ b/NEWS
@@ -3,9 +3,11 @@ PHP NEWS
03 Sep 2015, PHP 7.0.0 RC 2
- Core:
- . Fixed bug #70145 (From field incorrectly parsed from headers). (Anatol)
. Fixed bug #70300 (Syntactical inconsistency with new group use syntax).
(marcio dot web2 at gmail dot com)
+ . Fixed bug #70321 (Magic getter breaks reference to array property).
+ (Laruence)
+ . Fixed bug #70145 (From field incorrectly parsed from headers). (Anatol)
. Fixed bug causing exception traces with anon classes to be truncated. (Bob)
- PDO_OCI:
diff --git a/Zend/tests/bug70321.phpt b/Zend/tests/bug70321.phpt
new file mode 100644
index 0000000..19f691f
--- /dev/null
+++ b/Zend/tests/bug70321.phpt
@@ -0,0 +1,49 @@
+--TEST--
+bug #70321 (Magic getter breaks reference to array property)
+--FILE--
+<?php
+class foo implements arrayAccess
+{
+ private $bar;
+ public function __construct()
+ {
+ $this->bar = new bar();
+ }
+ public function & __get($key)
+ {
+ $bar = $this->bar;
+ return $bar;
+ }
+
+ public function & offsetGet($key) {
+ $bar = $this->bar;
+ return $bar;
+ }
+ public function offsetSet($key, $val) {
+ }
+ public function offsetUnset($key) {
+ }
+ public function offsetExists($key) {
+ }
+}
+class bar { public $onBaz = []; }
+
+$foo = new foo();
+$foo->bar->onBaz[] = function() {};
+var_dump($foo->bar->onBaz);
+
+$foo = new foo();
+$foo["bar"]->onBaz[] = function() {};
+var_dump($foo->bar->onBaz);
+?>
+--EXPECTF--
+array(1) {
+ [0]=>
+ object(Closure)#%d (0) {
+ }
+}
+array(1) {
+ [0]=>
+ object(Closure)#%d (0) {
+ }
+}
diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c
index 59f936d..76a2f21 100644
--- a/Zend/zend_execute.c
+++ b/Zend/zend_execute.c
@@ -1721,6 +1721,8 @@ convert_to_array:
zend_class_entry *ce = Z_OBJCE_P(container);
zend_error(E_NOTICE, "Indirect modification of overloaded element of %s has no
effect", ZSTR_VAL(ce->name));
}
+ } else if (UNEXPECTED(Z_REFCOUNT_P(retval) == 1)) {
+ ZVAL_UNREF(retval);
}
if (result != retval) {
ZVAL_INDIRECT(result, retval);
@@ -1925,6 +1927,8 @@ static zend_always_inline void zend_fetch_property_address(zval *result, zval
*c
(ptr = Z_OBJ_HT_P(container)->read_property(container, prop_ptr, type, cache_slot, result))
!= NULL) {
if (ptr != result) {
ZVAL_INDIRECT(result, ptr);
+ } else if (UNEXPECTED(Z_ISREF_P(ptr) && Z_REFCOUNT_P(ptr) == 1)) {
+ ZVAL_UNREF(ptr);
}
} else {
zend_throw_error(NULL, "Cannot access undefined property for object with overloaded
property access");
@@ -1937,6 +1941,8 @@ static zend_always_inline void zend_fetch_property_address(zval *result, zval
*c
zval *ptr = Z_OBJ_HT_P(container)->read_property(container, prop_ptr, type, cache_slot,
result);
if (ptr != result) {
ZVAL_INDIRECT(result, ptr);
+ } else if (UNEXPECTED(Z_ISREF_P(ptr) && Z_REFCOUNT_P(ptr) == 1)) {
+ ZVAL_UNREF(ptr);
}
} else {
zend_error(E_WARNING, "This object doesn't support property references");