com php-src: Improved fix for bug #70262: Zend/tests/bug70262.phpt Zend/zend_execute.c Zend/zend_vm_def.h Zend/zend _vm_execute.h
| From: | Xinchen Hui | Date: | Tue, 18 Aug 2015 10:07:31 +0000 |
| Subject: | com php-src: Improved fix for bug #70262: Zend/tests/bug70262.phpt Zend/zend_execute.c Zend/zend_vm_def.h Zend/zend _vm_execute.h | ||
| Groups: | php.cvs | ||
| Request: | Send a blank email to php-cvs+get-88580@lists.php.net to get a copy of this message | ||
Commit: 8df34610869566c5af3f21efa2575e6e2e262d74
Author: Xinchen Hui <laruence@php.net> Tue, 18 Aug 2015 18:07:31 +0800
Parents: cf9cdf97dbf9c26a6034762a3e28100472fd9021
Branches: master
Link: http://git.php.net/?p=php-src.git;a=commitdiff;h=8df34610869566c5af3f21efa2575e6e2e262d74
Log:
Improved fix for bug #70262
Bugs:
https://bugs.php.net/70262
Changed paths:
M Zend/tests/bug70262.phpt
M Zend/zend_execute.c
M Zend/zend_vm_def.h
M Zend/zend_vm_execute.h
Diff:
diff --git a/Zend/tests/bug70262.phpt b/Zend/tests/bug70262.phpt
index 42e7fe0..7e285e8 100644
--- a/Zend/tests/bug70262.phpt
+++ b/Zend/tests/bug70262.phpt
@@ -2,33 +2,29 @@
Bug #70262 (Accessing array crashes)
--FILE--
<?php
-class C {
- public $arguments;
- public function __construct($arg) {
- $this->arguments = $arg;
- }
-}
-function & a(&$arg) {
- $c = new C($arg);
- $arg[] = $c;
- return $c;
-}
+$array = array();
+$array[] = 1; // make this not immutable
-function c($arr) {
- a($arr)->arguments[0] = "bad";
+$extra = $array; // make the refcount == 2
+
+class A {
+ public function getObj($array) {
+ $obj = new Stdclass;
+ $obj->arr = $array; // make the refcount == 3;
+ return $obj;
+ }
}
-$arr = array();
-$arr[] = "foo";
-$arr[] = "bar";
-c($arr);
-var_dump($arr);
+$a = new A;
+$a->getObj($array) //use function call to get a refcount == 1 IS_VAR object
+ ->arr // FETCH_OBJ_W will EXTRACT_ZVAL_PTR because getObj() result a refcount == 1 object
(READY_TO_DESTROY)
+ [0] = "test"; //We will get a refcount == 3 array (not a IS_INDIRCT) in
ZEND_ASSIGN_DIM_SPEC_VAR_CONST_HANDLER
+
+var_dump($array);
?>
--EXPECT--
-array(2) {
+array(1) {
[0]=>
- string(3) "foo"
- [1]=>
- string(3) "bar"
+ int(1)
}
diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c
index c3d8990..dbf5c50 100644
--- a/Zend/zend_execute.c
+++ b/Zend/zend_execute.c
@@ -480,13 +480,8 @@ static zend_always_inline zval *_get_zval_ptr_ptr_var(uint32_t var, const
zend_e
if (EXPECTED(Z_TYPE_P(ret) == IS_INDIRECT)) {
*should_free = NULL;
ret = Z_INDIRECT_P(ret);
- } else if (!Z_REFCOUNTED_P(ret)) {
- *should_free = ret; /* immutable array may be converted to regular */
- } else if (Z_REFCOUNT_P(ret) == 1) {
- *should_free = ret;
} else {
- *should_free = NULL;
- Z_DELREF_P(ret);
+ *should_free = ret; /* immutable array may be converted to regular */
}
return ret;
}
diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h
index 9ee27d8..eceed13 100644
--- a/Zend/zend_vm_def.h
+++ b/Zend/zend_vm_def.h
@@ -7250,11 +7250,11 @@ ZEND_VM_HANDLER(156, ZEND_SEPARATE, VAR, UNUSED)
zval *var_ptr;
var_ptr = EX_VAR(opline->op1.var);
- if (UNEXPECTED(Z_ISREF_P(var_ptr))) {
- if (UNEXPECTED(Z_REFCOUNT_P(var_ptr) == 1)) {
- ZVAL_UNREF(var_ptr);
- }
- } else if (Z_COPYABLE_P(var_ptr) && Z_REFCOUNT_P(var_ptr) > 1) {
+ if (Z_TYPE_P(var_ptr) != IS_OBJECT &&
+ !Z_ISREF_P(var_ptr) &&
+ Z_REFCOUNTED_P(var_ptr) &&
+ Z_REFCOUNT_P(var_ptr) > 1) {
+
Z_DELREF_P(var_ptr);
ZVAL_DUP(EX_VAR(opline->op1.var), var_ptr);
}
diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h
index 8dd8881..cf1c7a1 100644
--- a/Zend/zend_vm_execute.h
+++ b/Zend/zend_vm_execute.h
@@ -19444,11 +19444,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL
ZEND_SEPARATE_SPEC_VAR_UNUSED_HANDL
zval *var_ptr;
var_ptr = EX_VAR(opline->op1.var);
- if (UNEXPECTED(Z_ISREF_P(var_ptr))) {
- if (UNEXPECTED(Z_REFCOUNT_P(var_ptr) == 1)) {
- ZVAL_UNREF(var_ptr);
- }
- } else if (Z_COPYABLE_P(var_ptr) && Z_REFCOUNT_P(var_ptr) > 1) {
+ if (Z_TYPE_P(var_ptr) != IS_OBJECT &&
+ !Z_ISREF_P(var_ptr) &&
+ Z_REFCOUNTED_P(var_ptr) &&
+ Z_REFCOUNT_P(var_ptr) > 1) {
+
Z_DELREF_P(var_ptr);
ZVAL_DUP(EX_VAR(opline->op1.var), var_ptr);
}