}
/* }}} */
-static zval *spl_array_get_dimension_ptr(int check_inherited, zval *object, zval *offset, int type) /* {{{ */
+static zval *spl_array_get_dimension_ptr(int check_inherited, spl_array_object *intern, zval *offset, int type) /* {{{ */
{
zval *retval;
zend_long index;
zend_string *offset_key;
- spl_array_object *intern = Z_SPLARRAY_P(object);
HashTable *ht = spl_array_get_hash_table(intern);
if (!offset || Z_ISUNDEF_P(offset)) {
}
} /* }}} */
+static int spl_array_has_dimension(zval *object, zval *offset, int check_empty);
+
static zval *spl_array_read_dimension_ex(int check_inherited, zval *object, zval *offset, int type, zval *rv) /* {{{ */
{
+ spl_array_object *intern = Z_SPLARRAY_P(object);
zval *ret;
- if (check_inherited) {
- spl_array_object *intern = Z_SPLARRAY_P(object);
+ if (check_inherited &&
+ (intern->fptr_offset_get || (type == BP_VAR_IS && intern->fptr_offset_has))) {
+ if (type == BP_VAR_IS) {
+ if (!spl_array_has_dimension(object, offset, 0)) {
+ return &EG(uninitialized_zval);
+ }
+ }
+
if (intern->fptr_offset_get) {
zval tmp;
if (!offset) {
return &EG(uninitialized_zval);
}
}
- ret = spl_array_get_dimension_ptr(check_inherited, object, offset, type);
+
+ ret = spl_array_get_dimension_ptr(check_inherited, intern, offset, type);
/* When in a write context,
* ZE has to be fooled into thinking this is in a reference set
if ((intern->ar_flags & SPL_ARRAY_ARRAY_AS_PROPS) != 0
&& !std_object_handlers.has_property(object, member, 2, NULL)) {
- return spl_array_get_dimension_ptr(1, object, member, type);
+ return spl_array_get_dimension_ptr(1, intern, member, type);
}
return std_object_handlers.get_property_ptr_ptr(object, member, type, cache_slot);
} /* }}} */
--- /dev/null
+--TEST--
+Bug #62059: ArrayObject and isset are not friends
+--FILE--
+<?php
+
+class MyArrayObject1 extends ArrayObject {
+ public function offsetGet($name) {
+ echo "offsetGet($name)\n";
+ return parent::offsetGet($name);
+ }
+ public function offsetExists($name) {
+ echo "offsetExists($name)\n";
+ return parent::offsetExists($name);
+ }
+}
+class MyArrayObject2 extends ArrayObject {
+ public function offsetGet($name) {
+ echo "offsetGet($name)\n";
+ return parent::offsetGet($name);
+ }
+}
+class MyArrayObject3 extends ArrayObject {
+ public function offsetExists($name) {
+ echo "offsetExists($name)\n";
+ return parent::offsetExists($name);
+ }
+}
+
+$arr = [1 => [1 => 42]];
+$ao = new ArrayObject($arr);
+var_dump(isset($ao[0][1]));
+var_dump(isset($ao[1][0]));
+var_dump(isset($ao[1][1]));
+$ao = new MyArrayObject1($arr);
+var_dump(isset($ao[0][1]));
+var_dump(isset($ao[1][0]));
+var_dump(isset($ao[1][1]));
+$ao = new MyArrayObject2($arr);
+var_dump(isset($ao[0][1]));
+var_dump(isset($ao[1][0]));
+var_dump(isset($ao[1][1]));
+$ao = new MyArrayObject3($arr);
+var_dump(isset($ao[0][1]));
+var_dump(isset($ao[1][0]));
+var_dump(isset($ao[1][1]));
+
+?>
+--EXPECT--
+bool(false)
+bool(false)
+bool(true)
+offsetExists(0)
+bool(false)
+offsetExists(1)
+offsetGet(1)
+bool(false)
+offsetExists(1)
+offsetGet(1)
+bool(true)
+bool(false)
+offsetGet(1)
+bool(false)
+offsetGet(1)
+bool(true)
+offsetExists(0)
+bool(false)
+offsetExists(1)
+bool(false)
+offsetExists(1)
+bool(true)