mirror of
https://github.com/php/php-src.git
synced 2024-09-21 18:07:23 +00:00
Improved fix for bug #70262
This commit is contained in:
parent
cf9cdf97db
commit
8df3461086
@ -2,33 +2,29 @@
|
||||
Bug #70262 (Accessing array crashes)
|
||||
--FILE--
|
||||
<?php
|
||||
class C {
|
||||
public $arguments;
|
||||
public function __construct($arg) {
|
||||
$this->arguments = $arg;
|
||||
|
||||
$array = array();
|
||||
$array[] = 1; // make this not immutable
|
||||
|
||||
$extra = $array; // make the refcount == 2
|
||||
|
||||
class A {
|
||||
public function getObj($array) {
|
||||
$obj = new Stdclass;
|
||||
$obj->arr = $array; // make the refcount == 3;
|
||||
return $obj;
|
||||
}
|
||||
}
|
||||
|
||||
function & a(&$arg) {
|
||||
$c = new C($arg);
|
||||
$arg[] = $c;
|
||||
return $c;
|
||||
}
|
||||
$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
|
||||
|
||||
function c($arr) {
|
||||
a($arr)->arguments[0] = "bad";
|
||||
}
|
||||
|
||||
$arr = array();
|
||||
$arr[] = "foo";
|
||||
$arr[] = "bar";
|
||||
c($arr);
|
||||
var_dump($arr);
|
||||
var_dump($array);
|
||||
?>
|
||||
--EXPECT--
|
||||
array(2) {
|
||||
array(1) {
|
||||
[0]=>
|
||||
string(3) "foo"
|
||||
[1]=>
|
||||
string(3) "bar"
|
||||
int(1)
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user