diff options
author | andrewnester <andrew.nester.dev@gmail.com> | 2017-03-02 16:59:32 +0300 |
---|---|---|
committer | Nikita Popov <nikita.ppv@gmail.com> | 2017-03-09 00:10:00 +0100 |
commit | 8f799137d7ed6634687e272cea798cac56da4b98 (patch) | |
tree | 92be07e9f54dbd2b71c153f780b1127f152b0d4a | |
parent | 1a19b97ac3e824138a5fde4b86638b6d69f64a78 (diff) | |
download | php-git-8f799137d7ed6634687e272cea798cac56da4b98.tar.gz |
Fixed bug #74058
Fall back from get_property_ptr_ptr to read_property if offsetGet
is overridden.
-rw-r--r-- | NEWS | 3 | ||||
-rw-r--r-- | ext/spl/spl_array.c | 5 | ||||
-rw-r--r-- | ext/spl/tests/bug74058.phpt | 81 |
3 files changed, 89 insertions, 0 deletions
@@ -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" +} |