summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikita Popov <nikic@php.net>2016-06-28 21:34:20 +0200
committerNikita Popov <nikic@php.net>2016-06-28 21:34:20 +0200
commit9b8f1d6037a0cee0bd7d002925ab54bcaec25eb9 (patch)
treebccd07b7643cc7486eefcd30c177a95a0830be1b
parentfafe01b07bfcb4f4a9088dd89195f2f5acba8fd0 (diff)
downloadphp-git-9b8f1d6037a0cee0bd7d002925ab54bcaec25eb9.tar.gz
Don't use FUNC_ARG fetches for call_user_func()
This makes no sense -- SEND_USER can't even handle INDIRECTs.
-rw-r--r--Zend/tests/call_user_func_007.phpt18
-rw-r--r--Zend/zend_compile.c14
2 files changed, 20 insertions, 12 deletions
diff --git a/Zend/tests/call_user_func_007.phpt b/Zend/tests/call_user_func_007.phpt
new file mode 100644
index 0000000000..f73f14b1ff
--- /dev/null
+++ b/Zend/tests/call_user_func_007.phpt
@@ -0,0 +1,18 @@
+--TEST--
+call_user_func() should not use FUNC_ARG fetches
+--FILE--
+<?php
+
+function foo(&$ref) { $ref = 24; }
+
+$a = [];
+call_user_func('foo', $a[0][0]);
+var_dump($a);
+
+?>
+--EXPECTF--
+Notice: Undefined offset: 0 in %s on line %d
+
+Warning: Parameter 1 to foo() expected to be a reference, value given in %s on line %d
+array(0) {
+}
diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c
index 3af1fb3861..bc4b2fd8f3 100644
--- a/Zend/zend_compile.c
+++ b/Zend/zend_compile.c
@@ -3070,19 +3070,9 @@ int zend_compile_func_cuf(znode *result, zend_ast_list *args, zend_string *lcnam
zend_ast *arg_ast = args->child[i];
znode arg_node;
zend_op *opline;
- zend_bool send_user = 0;
- if (zend_is_variable(arg_ast) && !zend_is_call(arg_ast)) {
- zend_compile_var(&arg_node, arg_ast, BP_VAR_FUNC_ARG | (i << BP_VAR_SHIFT));
- send_user = 1;
- } else {
- zend_compile_expr(&arg_node, arg_ast);
- if (arg_node.op_type & (IS_VAR|IS_CV)) {
- send_user = 1;
- }
- }
-
- if (send_user) {
+ zend_compile_expr(&arg_node, arg_ast);
+ if (arg_node.op_type & (IS_VAR|IS_CV)) {
opline = zend_emit_op(NULL, ZEND_SEND_USER, &arg_node, NULL);
} else {
opline = zend_emit_op(NULL, ZEND_SEND_VAL, &arg_node, NULL);