Fixed bug #39297 (Memory corryption because of indirect modification of overloaded array).

This commit is contained in:
Dmitry Stogov 2006-11-08 13:38:44 +00:00
parent 15aca2c17d
commit f8b3df2bf2
2 changed files with 58 additions and 0 deletions

45
Zend/tests/bug39297.phpt Executable file
View File

@ -0,0 +1,45 @@
--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)

View File

@ -477,6 +477,19 @@ zval *zend_std_read_dimension(zval *object, zval *offset, int type TSRMLS_DC)
/* 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);