--- /dev/null
+--TEST--
+Bug #39297 (Memory corryption because of indirect modification of overloaded array)
+--FILE--
+<?php
+function compareByRef(&$first, &$second) {
+ return $first === $second;
+}
+
+class MyTree implements ArrayAccess {
+ public $parent;
+ public $children = array();
+
+ public function offsetExists($offset) {
+ }
+
+ public function offsetUnset($offset) {
+ }
+
+ public function offsetSet($offset, $value) {
+ echo "offsetSet()\n";
+ $cannonicalName = strtolower($offset);
+ $this->children[$cannonicalName] = $value;
+ $value->parent = $this;
+ }
+
+ public function offsetGet($offset) {
+ echo "offsetGet()\n";
+ $cannonicalName = strtolower($offset);
+ return $this->children[$cannonicalName];
+ }
+
+}
+
+$id = 'Test';
+
+$root = new MyTree();
+$child = new MyTree();
+$root[$id] = $child;
+
+var_dump(compareByRef($root[$id], $child));
+?>
+--EXPECT--
+offsetSet()
+offsetGet()
+bool(true)
/* Undo PZVAL_LOCK() */
retval->refcount--;
+ if ((type == BP_VAR_W || type == BP_VAR_RW || type == BP_VAR_UNSET) && retval->refcount > 0) {
+ zval *tmp = retval;
+
+ ALLOC_ZVAL(retval);
+ *retval = *tmp;
+ zval_copy_ctor(retval);
+ retval->is_ref = 0;
+ retval->refcount = 0;
+ if (Z_TYPE_P(retval) != IS_OBJECT) {
+ zend_error(E_NOTICE, "Indirect modification of overloaded element of %s has no effect", ce->name);
+ }
+ }
+
return retval;
} else {
zend_error(E_ERROR, "Cannot use object of type %v as array", ce->name);