Skip to content

Commit a879215

Browse files
committed
Fix SEND_ARRAY+PREFER_REF SHM corruption
Make the behavior consistent between namespaced and not and with PHP 5.6.
1 parent aa9f8e6 commit a879215

File tree

3 files changed

+51
-48
lines changed

3 files changed

+51
-48
lines changed
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
--TEST--
2+
call_user_func_array() passes value to prefer-ref arg if element wasn't a reference
3+
--FILE--
4+
<?php
5+
6+
namespace {
7+
call_user_func_array('array_multisort', [[3, 2, 1]]);
8+
9+
$args = [[3, 2, 1]];
10+
call_user_func_array('array_multisort', $args);
11+
var_dump($args);
12+
unset($args);
13+
}
14+
15+
namespace Foo {
16+
call_user_func_array('array_multisort', [[3, 2, 1]]);
17+
18+
$args = [[3, 2, 1]];
19+
call_user_func_array('array_multisort', $args);
20+
var_dump($args);
21+
unset($args);
22+
}
23+
24+
?>
25+
--EXPECT--
26+
array(1) {
27+
[0]=>
28+
array(3) {
29+
[0]=>
30+
int(3)
31+
[1]=>
32+
int(2)
33+
[2]=>
34+
int(1)
35+
}
36+
}
37+
array(1) {
38+
[0]=>
39+
array(3) {
40+
[0]=>
41+
int(3)
42+
[1]=>
43+
int(2)
44+
[2]=>
45+
int(1)
46+
}
47+
}

Zend/zend_vm_def.h

Lines changed: 2 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -4600,22 +4600,6 @@ ZEND_VM_C_LABEL(send_array):
46004600
ht = Z_ARRVAL_P(args);
46014601
zend_vm_stack_extend_call_frame(&EX(call), 0, zend_hash_num_elements(ht));
46024602

4603-
if (OP1_TYPE != IS_CONST && OP1_TYPE != IS_TMP_VAR && Z_IMMUTABLE_P(args)) {
4604-
int separate = 0;
4605-
4606-
/* check if any of arguments are going to be passed by reference */
4607-
for (arg_num = 0; arg_num < zend_hash_num_elements(ht); arg_num++) {
4608-
if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num + 1)) {
4609-
separate = 1;
4610-
break;
4611-
}
4612-
}
4613-
if (separate) {
4614-
zval_copy_ctor(args);
4615-
ht = Z_ARRVAL_P(args);
4616-
}
4617-
}
4618-
46194603
arg_num = 1;
46204604
param = ZEND_CALL_ARG(EX(call), 1);
46214605
ZEND_HASH_FOREACH_VAL(ht, arg) {
@@ -4641,21 +4625,15 @@ ZEND_VM_C_LABEL(send_array):
46414625

46424626
break;
46434627
}
4644-
4645-
ZVAL_NEW_REF(arg, arg);
46464628
}
4647-
Z_ADDREF_P(arg);
4648-
} else{
4629+
} else {
46494630
if (Z_ISREF_P(arg) &&
46504631
!(EX(call)->func->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE)) {
46514632
/* don't separate references for __call */
46524633
arg = Z_REFVAL_P(arg);
46534634
}
4654-
if (Z_OPT_REFCOUNTED_P(arg)) {
4655-
Z_ADDREF_P(arg);
4656-
}
46574635
}
4658-
ZVAL_COPY_VALUE(param, arg);
4636+
ZVAL_COPY(param, arg);
46594637
ZEND_CALL_NUM_ARGS(EX(call))++;
46604638
arg_num++;
46614639
param++;

Zend/zend_vm_execute.h

Lines changed: 2 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1132,22 +1132,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_ARRAY_SPEC_HANDLER(ZEND_O
11321132
ht = Z_ARRVAL_P(args);
11331133
zend_vm_stack_extend_call_frame(&EX(call), 0, zend_hash_num_elements(ht));
11341134

1135-
if (opline->op1_type != IS_CONST && opline->op1_type != IS_TMP_VAR && Z_IMMUTABLE_P(args)) {
1136-
int separate = 0;
1137-
1138-
/* check if any of arguments are going to be passed by reference */
1139-
for (arg_num = 0; arg_num < zend_hash_num_elements(ht); arg_num++) {
1140-
if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num + 1)) {
1141-
separate = 1;
1142-
break;
1143-
}
1144-
}
1145-
if (separate) {
1146-
zval_copy_ctor(args);
1147-
ht = Z_ARRVAL_P(args);
1148-
}
1149-
}
1150-
11511135
arg_num = 1;
11521136
param = ZEND_CALL_ARG(EX(call), 1);
11531137
ZEND_HASH_FOREACH_VAL(ht, arg) {
@@ -1173,21 +1157,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_ARRAY_SPEC_HANDLER(ZEND_O
11731157

11741158
break;
11751159
}
1176-
1177-
ZVAL_NEW_REF(arg, arg);
11781160
}
1179-
Z_ADDREF_P(arg);
1180-
} else{
1161+
} else {
11811162
if (Z_ISREF_P(arg) &&
11821163
!(EX(call)->func->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE)) {
11831164
/* don't separate references for __call */
11841165
arg = Z_REFVAL_P(arg);
11851166
}
1186-
if (Z_OPT_REFCOUNTED_P(arg)) {
1187-
Z_ADDREF_P(arg);
1188-
}
11891167
}
1190-
ZVAL_COPY_VALUE(param, arg);
1168+
ZVAL_COPY(param, arg);
11911169
ZEND_CALL_NUM_ARGS(EX(call))++;
11921170
arg_num++;
11931171
param++;

0 commit comments

Comments
 (0)