1
0
mirror of https://github.com/php/php-src.git synced 2026-03-24 00:02:20 +01:00

Fix SEND_UNPACK array separation

Separating only immutable arrays is not enough.
This commit is contained in:
Nikita Popov
2016-04-16 22:33:23 +02:00
parent 15d1d4f45b
commit d1a38743a5
3 changed files with 42 additions and 6 deletions

View File

@@ -0,0 +1,36 @@
--TEST--
Array must be separated if unpacking by reference
--FILE--
<?php
function inc(&... $args) {
foreach ($args as &$arg) {
$arg++;
}
}
$arr = [1, 2];
$arr[] = 3;
$arr2 = $arr;
inc(...$arr);
var_dump($arr);
var_dump($arr2);
?>
--EXPECT--
array(3) {
[0]=>
int(2)
[1]=>
int(3)
[2]=>
int(4)
}
array(3) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
int(3)
}

View File

@@ -4422,7 +4422,7 @@ ZEND_VM_C_LABEL(send_again):
zend_vm_stack_extend_call_frame(&EX(call), arg_num - 1, zend_hash_num_elements(ht));
if (OP1_TYPE != IS_CONST && OP1_TYPE != IS_TMP_VAR && Z_IMMUTABLE_P(args)) {
if (OP1_TYPE != IS_CONST && OP1_TYPE != IS_TMP_VAR && Z_REFCOUNT_P(args) > 1) {
uint32_t i;
int separate = 0;
@@ -4434,7 +4434,7 @@ ZEND_VM_C_LABEL(send_again):
}
}
if (separate) {
zval_copy_ctor(args);
SEPARATE_ARRAY(args);
ht = Z_ARRVAL_P(args);
}
}
@@ -4448,7 +4448,7 @@ ZEND_VM_C_LABEL(send_again):
top = ZEND_CALL_ARG(EX(call), arg_num);
if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
if (!Z_IMMUTABLE_P(args)) {
if (Z_REFCOUNT_P(args) == 1) {
ZVAL_MAKE_REF(arg);
Z_ADDREF_P(arg);
ZVAL_REF(top, Z_REF_P(arg));

View File

@@ -954,7 +954,7 @@ send_again:
zend_vm_stack_extend_call_frame(&EX(call), arg_num - 1, zend_hash_num_elements(ht));
if (opline->op1_type != IS_CONST && opline->op1_type != IS_TMP_VAR && Z_IMMUTABLE_P(args)) {
if (opline->op1_type != IS_CONST && opline->op1_type != IS_TMP_VAR && Z_REFCOUNT_P(args) > 1) {
uint32_t i;
int separate = 0;
@@ -966,7 +966,7 @@ send_again:
}
}
if (separate) {
zval_copy_ctor(args);
SEPARATE_ARRAY(args);
ht = Z_ARRVAL_P(args);
}
}
@@ -980,7 +980,7 @@ send_again:
top = ZEND_CALL_ARG(EX(call), arg_num);
if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
if (!Z_IMMUTABLE_P(args)) {
if (Z_REFCOUNT_P(args) == 1) {
ZVAL_MAKE_REF(arg);
Z_ADDREF_P(arg);
ZVAL_REF(top, Z_REF_P(arg));