com php-src: Fixed bug #68896 (Changing ArrayObject value cause Segment Fault): Zend/tests/bug68896.phpt Zend/zend_execute.c

From: Date: Mon, 26 Jan 2015 08:25:05 +0000
Subject: com php-src: Fixed bug #68896 (Changing ArrayObject value cause Segment Fault): Zend/tests/bug68896.phpt Zend/zend_execute.c
Groups: php.cvs 
Request: Send a blank email to php-cvs+get-84365@lists.php.net to get a copy of this message
Commit: 371dc9b6a659399ede7d3c784f3c6ff800045ab2 Author: Dmitry Stogov <dmitry@zend.com> Mon, 26 Jan 2015 11:25:05 +0300 Parents: 91045c4d74c594ec56d135ec9ecec4f007918a06 Branches: master Link: http://git.php.net/?p=php-src.git;a=commitdiff;h=371dc9b6a659399ede7d3c784f3c6ff800045ab2 Log: Fixed bug #68896 (Changing ArrayObject value cause Segment Fault) Bugs: https://bugs.php.net/68896 Changed paths: A Zend/tests/bug68896.phpt M Zend/zend_execute.c Diff: diff --git a/Zend/tests/bug68896.phpt b/Zend/tests/bug68896.phpt new file mode 100644 index 0000000..31823a2 --- /dev/null +++ b/Zend/tests/bug68896.phpt @@ -0,0 +1,31 @@ +--TEST-- +Bug #68896 (Changing ArrayObject value cause Segment Fault) +--FILE-- +<?php +class A implements ArrayAccess { + private $a = []; + function offsetGet($offset) { + return $this->a[$offset]; + } + function offsetSet($offset, $value) { + $this->a[$offset] = $value; + } + function offsetExists($offset) { + isset($this->a[$offset]); + } + function offsetUnset($offset) { + unset($this->a[$offset]); + } +} + +$obj = new ArrayObject(["a" => 1]); +$obj["a"] .= "test"; +var_dump($obj["a"]); + +$obj = new A; +$obj["a"] = 1; +$obj["a"] .= "test"; +var_dump($obj["a"]); +--EXPECT-- +string(5) "1test" +string(5) "1test" diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index c71c032..3092d05 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -925,7 +925,7 @@ static zend_always_inline void zend_assign_to_object_dim(zval *retval, zval *obj static void zend_binary_assign_op_obj_dim(zval *object, zval *property, zval *value, zval *retval, int (*binary_op)(zval *result, zval *op1, zval *op2)) { zval *z; - zval rv; + zval rv, res; if (Z_OBJ_HT_P(object)->read_dimension && (z = Z_OBJ_HT_P(object)->read_dimension(object, property, BP_VAR_R, &rv)) != NULL) { @@ -939,14 +939,15 @@ static void zend_binary_assign_op_obj_dim(zval *object, zval *property, zval *va } ZVAL_COPY_VALUE(z, value); } - ZVAL_DEREF(z); - SEPARATE_ZVAL_NOREF(z); - binary_op(z, z, value); - Z_OBJ_HT_P(object)->write_dimension(object, property, z); + binary_op(&res, Z_ISREF_P(z) ? Z_REFVAL_P(z) : z, value); + Z_OBJ_HT_P(object)->write_dimension(object, property, &res); + if (z == &rv) { + zval_ptr_dtor(&rv); + } if (retval) { - ZVAL_COPY(retval, z); + ZVAL_COPY(retval, &res); } - zval_ptr_dtor(z); + zval_ptr_dtor(&res); } else { zend_error(E_WARNING, "Attempt to assign property of non-object"); if (retval) {

« previous php.cvs (#84365) next »