summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorandrewnester <andrew.nester.dev@gmail.com>2017-03-02 16:59:32 +0300
committerNikita Popov <nikita.ppv@gmail.com>2017-03-09 00:10:00 +0100
commit8f799137d7ed6634687e272cea798cac56da4b98 (patch)
tree92be07e9f54dbd2b71c153f780b1127f152b0d4a
parent1a19b97ac3e824138a5fde4b86638b6d69f64a78 (diff)
downloadphp-git-8f799137d7ed6634687e272cea798cac56da4b98.tar.gz
Fixed bug #74058
Fall back from get_property_ptr_ptr to read_property if offsetGet is overridden.
-rw-r--r--NEWS3
-rw-r--r--ext/spl/spl_array.c5
-rw-r--r--ext/spl/tests/bug74058.phpt81
3 files changed, 89 insertions, 0 deletions
diff --git a/NEWS b/NEWS
index 3df1bdfef9..3b6199f92a 100644
--- a/NEWS
+++ b/NEWS
@@ -6,6 +6,9 @@ PHP NEWS
. Fixed bug #74004 (LIBXML_NOWARNING flag ingnored on loadHTML*).
(somedaysummer)
+- SPL:
+ . Fixed bug #74058 (ArrayObject can not notice changes). (Andrew Nester)
+
16 Mar 2017, PHP 7.1.3
- Core:
diff --git a/ext/spl/spl_array.c b/ext/spl/spl_array.c
index d0cadcf167..8095c8cb19 100644
--- a/ext/spl/spl_array.c
+++ b/ext/spl/spl_array.c
@@ -901,6 +901,11 @@ static zval *spl_array_get_property_ptr_ptr(zval *object, zval *member, int type
if ((intern->ar_flags & SPL_ARRAY_ARRAY_AS_PROPS) != 0
&& !std_object_handlers.has_property(object, member, 2, NULL)) {
+ /* If object has offsetGet() overridden, then fallback to read_property,
+ * which will call offsetGet(). */
+ if (intern->fptr_offset_get) {
+ return NULL;
+ }
return spl_array_get_dimension_ptr(1, intern, member, type);
}
return std_object_handlers.get_property_ptr_ptr(object, member, type, cache_slot);
diff --git a/ext/spl/tests/bug74058.phpt b/ext/spl/tests/bug74058.phpt
new file mode 100644
index 0000000000..a416d8f15a
--- /dev/null
+++ b/ext/spl/tests/bug74058.phpt
@@ -0,0 +1,81 @@
+--TEST--
+Bug #74058 (ArrayObject can not notice changes)
+--FILE--
+<?php
+
+class MyArrayObject extends ArrayObject
+{
+ public function __construct($input = [])
+ {
+ parent::__construct($input, ArrayObject::ARRAY_AS_PROPS);
+ }
+
+ public function offsetSet($x, $v)
+ {
+ echo "offsetSet('{$x}')\n";
+ return parent::offsetSet($x, $v);
+ }
+
+ public function offsetGet($x)
+ {
+ echo "offsetGet('{$x}')\n";
+ return parent::offsetGet($x);
+ }
+}
+
+class MyArray extends ArrayObject
+{
+ public function __construct($input = [])
+ {
+ parent::__construct($input);
+ }
+
+ public function offsetSet($x, $v)
+ {
+ echo "offsetSet('{$x}')\n";
+ return parent::offsetSet($x, $v);
+ }
+
+ public function offsetGet($x)
+ {
+ echo "offsetGet('{$x}')\n";
+ return parent::offsetGet($x);
+ }
+}
+
+$x = new MyArrayObject;
+$x->a1 = new stdClass();
+var_dump($x->a1);
+
+$x->a1->b = 'some value';
+var_dump($x->a1);
+
+$y = new MyArray();
+$y['a2'] = new stdClass();
+var_dump($y['a2']);
+
+$y['a2']->b = 'some value';
+var_dump($y['a2']);
+
+?>
+--EXPECTF--
+offsetSet('a1')
+offsetGet('a1')
+object(stdClass)#%s (0) {
+}
+offsetGet('a1')
+offsetGet('a1')
+object(stdClass)#%s (1) {
+ ["b"]=>
+ string(10) "some value"
+}
+offsetSet('a2')
+offsetGet('a2')
+object(stdClass)#%s (0) {
+}
+offsetGet('a2')
+offsetGet('a2')
+object(stdClass)#%s (1) {
+ ["b"]=>
+ string(10) "some value"
+}