diff options
Diffstat (limited to 'Zend')
| -rw-r--r-- | Zend/tests/ArrayAccess_indirect_append.phpt | 43 | ||||
| -rw-r--r-- | Zend/tests/bug69955.phpt | 2 | ||||
| -rw-r--r-- | Zend/tests/bug71731.phpt | 64 | ||||
| -rw-r--r-- | Zend/zend_object_handlers.c | 17 |
4 files changed, 122 insertions, 4 deletions
diff --git a/Zend/tests/ArrayAccess_indirect_append.phpt b/Zend/tests/ArrayAccess_indirect_append.phpt new file mode 100644 index 0000000000..6f3da7c46c --- /dev/null +++ b/Zend/tests/ArrayAccess_indirect_append.phpt @@ -0,0 +1,43 @@ +--TEST-- +Using indirect append on ArrayAccess object +--FILE-- +<?php + +class AA implements ArrayAccess { + private $data = []; + public function &offsetGet($name) { + if (null === $name) { + return $this->data[]; + } else { + return $this->data[$name]; + } + } + public function offsetSet($name, $value) { + $this->data[$name] = $value; + } + public function offsetUnset($name) {} + public function offsetExists($name) {} +} + +$aa = new AA; +$aa[3] = 1; +$aa[][][0] = 2; +var_dump($aa); + +?> +--EXPECT-- +object(AA)#1 (1) { + ["data":"AA":private]=> + array(2) { + [3]=> + int(1) + [4]=> + array(1) { + [0]=> + array(1) { + [0]=> + int(2) + } + } + } +} diff --git a/Zend/tests/bug69955.phpt b/Zend/tests/bug69955.phpt index b6d74242ee..33c36850c0 100644 --- a/Zend/tests/bug69955.phpt +++ b/Zend/tests/bug69955.phpt @@ -27,8 +27,6 @@ $c10 = new C10; var_dump($c10[] += 5); --EXPECTF-- Inside C10::offsetGet - -Notice: Undefined variable: offset in %sbug69955.php on line 10 NULL Inside C10::offsetSet diff --git a/Zend/tests/bug71731.phpt b/Zend/tests/bug71731.phpt new file mode 100644 index 0000000000..46a79f1a34 --- /dev/null +++ b/Zend/tests/bug71731.phpt @@ -0,0 +1,64 @@ +--TEST-- +Bug #71731: Null coalescing operator and ArrayAccess +--FILE-- +<?php + +class AA implements ArrayAccess { + private $data = []; + public function offsetExists($name) { + echo "offsetExists($name)\n"; + return array_key_exists($name, $this->data); + } + public function &offsetGet($name) { + echo "offsetGet($name)\n"; + if (!array_key_exists($name, $this->data)) { + throw new Exception('Unknown offset'); + } + return $this->data[$name]; + } + public function offsetSet($name, $value) { + echo "offsetSet($name)\n"; + $this->data[$name] = $value; + } + public function offsetUnset($name) { + echo "offsetUnset($name)\n"; + unset($this->data[$name]); + } +} + +$aa = new AA; +var_dump(isset($aa[0][1][2])); +var_dump(isset($aa[0]->foo)); +var_dump($aa[0] ?? 42); +var_dump($aa[0][1][2] ?? 42); + +$aa[0] = new AA; +$aa[0][1] = new AA; +var_dump(isset($aa[0][1][2])); +var_dump($aa[0][1][2] ?? 42); + +?> +--EXPECT-- +offsetExists(0) +bool(false) +offsetExists(0) +bool(false) +offsetExists(0) +int(42) +offsetExists(0) +int(42) +offsetSet(0) +offsetGet(0) +offsetSet(1) +offsetExists(0) +offsetGet(0) +offsetExists(1) +offsetGet(1) +offsetExists(2) +bool(false) +offsetExists(0) +offsetGet(0) +offsetExists(1) +offsetGet(1) +offsetExists(2) +int(42) diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index c66f8ad7c3..7b31fdc524 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -710,13 +710,26 @@ zval *zend_std_read_dimension(zval *object, zval *offset, int type, zval *rv) /* zval tmp; if (EXPECTED(instanceof_function_ex(ce, zend_ce_arrayaccess, 1) != 0)) { - if(offset == NULL) { + if (offset == NULL) { /* [] construct */ - ZVAL_UNDEF(&tmp); + ZVAL_NULL(&tmp); offset = &tmp; } else { SEPARATE_ARG_IF_REF(offset); } + + if (type == BP_VAR_IS) { + zend_call_method_with_1_params(object, ce, NULL, "offsetexists", rv, offset); + if (UNEXPECTED(Z_ISUNDEF_P(rv))) { + return NULL; + } + if (!i_zend_is_true(rv)) { + zval_ptr_dtor(rv); + return &EG(uninitialized_zval); + } + zval_ptr_dtor(rv); + } + zend_call_method_with_1_params(object, ce, NULL, "offsetget", rv, offset); zval_ptr_dtor(offset); |
