Skip to content

Commit 54c3a6d

Browse files
committed
Fix by-ref unpack sending of offsets
Fixes phpGH-12404
1 parent d2a9edf commit 54c3a6d

File tree

5 files changed

+48
-1
lines changed

5 files changed

+48
-1
lines changed

Zend/tests/arg_unpack/gh14202.phpt

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
--TEST--
2+
GH-14202: Fetch splat arg value by RW
3+
--FILE--
4+
<?php
5+
$args = [1];
6+
$ref = [&$args];
7+
function test(&$v) {
8+
$v = 7;
9+
};
10+
test(...$ref[0]);
11+
var_dump($args[0]);
12+
?>
13+
--EXPECT--
14+
int(7)
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
--TEST--
2+
GH-14202: Fetching splat arg value by RW has some side-effects
3+
--FILE--
4+
<?php
5+
function test($byVal) {
6+
var_dump($byVal);
7+
}
8+
try {
9+
test(...$foo['bar']);
10+
} catch (Error $e) {
11+
echo $e->getMessage(), "\n";
12+
}
13+
var_dump($foo);
14+
?>
15+
--EXPECTF--
16+
Warning: Undefined variable $foo in %s on line %d
17+
18+
Warning: Undefined array key "bar" in %s on line %d
19+
Only arrays and Traversables can be unpacked
20+
array(1) {
21+
["bar"]=>
22+
NULL
23+
}

Zend/zend_compile.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3685,7 +3685,11 @@ static uint32_t zend_compile_args(
36853685
uses_arg_unpack = 1;
36863686
fbc = NULL;
36873687

3688-
zend_compile_expr(&arg_node, arg->child[0]);
3688+
if (zend_is_variable(arg->child[0])) {
3689+
zend_compile_var(&arg_node, arg->child[0], BP_VAR_RW, /* by_ref */ false);
3690+
} else {
3691+
zend_compile_expr(&arg_node, arg->child[0]);
3692+
}
36893693
opline = zend_emit_op(NULL, ZEND_SEND_UNPACK, &arg_node, NULL);
36903694
opline->op2.num = arg_count;
36913695
opline->result.var = EX_NUM_TO_VAR(arg_count - 1);

Zend/zend_vm_def.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5306,6 +5306,9 @@ ZEND_VM_C_LABEL(send_again):
53065306

53075307
zend_iterator_dtor(iter);
53085308
}
5309+
} else if (Z_TYPE_P(args)) {
5310+
args = Z_INDIRECT_P(args);
5311+
ZEND_VM_C_GOTO(send_again);
53095312
} else if (EXPECTED(Z_ISREF_P(args))) {
53105313
args = Z_REFVAL_P(args);
53115314
ZEND_VM_C_GOTO(send_again);

Zend/zend_vm_execute.h

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)