summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXinchen Hui <laruence@php.net>2015-03-03 17:34:45 +0800
committerXinchen Hui <laruence@php.net>2015-03-03 18:11:56 +0800
commit7ad6711a4dcb092e2125d36ec623f38a22153e73 (patch)
tree2b75d67091dbdb74a16d429e3500bcd4cb0cb9da
parent70bd500645da48f3c2eb2ebbe916a2abe51a48e0 (diff)
downloadphp-git-7ad6711a4dcb092e2125d36ec623f38a22153e73.tar.gz
Fixed bug #69167 (call_user_func does not support references anymore)
-rw-r--r--Zend/tests/bug69167.phpt17
-rw-r--r--Zend/zend_API.c11
-rw-r--r--Zend/zend_vm_def.h4
-rw-r--r--Zend/zend_vm_execute.h12
4 files changed, 42 insertions, 2 deletions
diff --git a/Zend/tests/bug69167.phpt b/Zend/tests/bug69167.phpt
new file mode 100644
index 0000000000..79326ed583
--- /dev/null
+++ b/Zend/tests/bug69167.phpt
@@ -0,0 +1,17 @@
+--TEST--
+Bug #69167 (call_user_func does not support references anymore)
+--FILE--
+<?php
+function l($m) {
+ echo $m . "\n";
+}
+
+$cb = 'l';
+call_user_func($cb, 'hi');
+
+$cb2 = &$cb;
+call_user_func($cb2, 'hi2');
+?>
+--EXPECT--
+hi
+hi2
diff --git a/Zend/zend_API.c b/Zend/zend_API.c
index 693a8340f8..88687796cc 100644
--- a/Zend/zend_API.c
+++ b/Zend/zend_API.c
@@ -3017,6 +3017,7 @@ ZEND_API zend_bool zend_is_callable_ex(zval *callable, zend_object *object, uint
return 0;
}
+again:
switch (Z_TYPE_P(callable)) {
case IS_STRING:
if (object) {
@@ -3160,7 +3161,6 @@ ZEND_API zend_bool zend_is_callable_ex(zval *callable, zend_object *object, uint
}
}
return 0;
-
case IS_OBJECT:
if (Z_OBJ_HANDLER_P(callable, get_closure) && Z_OBJ_HANDLER_P(callable, get_closure)(callable, &fcc->calling_scope, &fcc->function_handler, &fcc->object) == SUCCESS) {
fcc->called_scope = fcc->calling_scope;
@@ -3174,7 +3174,14 @@ ZEND_API zend_bool zend_is_callable_ex(zval *callable, zend_object *object, uint
return 1;
}
/* break missing intentionally */
-
+ if (callable_name) {
+ *callable_name = zval_get_string(callable);
+ }
+ if (error) zend_spprintf(error, 0, "no array or string given");
+ return 0;
+ case IS_REFERENCE:
+ callable = Z_REFVAL_P(callable);
+ goto again;
default:
if (callable_name) {
*callable_name = zval_get_string(callable);
diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h
index 2e9ffd6448..497f76d666 100644
--- a/Zend/zend_vm_def.h
+++ b/Zend/zend_vm_def.h
@@ -2735,6 +2735,10 @@ ZEND_VM_HANDLER(118, ZEND_INIT_USER_CALL, CONST, CONST|TMPVAR|CV)
zend_class_entry *called_scope;
zend_object *object;
+ if (OP2_TYPE & (IS_VAR|IS_CV)) {
+ ZVAL_DEREF(function_name);
+ }
+
if (zend_is_callable_ex(function_name, NULL, 0, NULL, &fcc, &error)) {
if (error) {
efree(error);
diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h
index 465ecc6dd4..c4bd7b7d0a 100644
--- a/Zend/zend_vm_execute.h
+++ b/Zend/zend_vm_execute.h
@@ -4587,6 +4587,10 @@ static int ZEND_FASTCALL ZEND_INIT_USER_CALL_SPEC_CONST_CONST_HANDLER(ZEND_OPCO
zend_class_entry *called_scope;
zend_object *object;
+ if (IS_CONST & (IS_VAR|IS_CV)) {
+ ZVAL_DEREF(function_name);
+ }
+
if (zend_is_callable_ex(function_name, NULL, 0, NULL, &fcc, &error)) {
if (error) {
efree(error);
@@ -7492,6 +7496,10 @@ static int ZEND_FASTCALL ZEND_INIT_USER_CALL_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_
zend_class_entry *called_scope;
zend_object *object;
+ if (IS_CV & (IS_VAR|IS_CV)) {
+ ZVAL_DEREF(function_name);
+ }
+
if (zend_is_callable_ex(function_name, NULL, 0, NULL, &fcc, &error)) {
if (error) {
efree(error);
@@ -8646,6 +8654,10 @@ static int ZEND_FASTCALL ZEND_INIT_USER_CALL_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPC
zend_class_entry *called_scope;
zend_object *object;
+ if ((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) {
+ ZVAL_DEREF(function_name);
+ }
+
if (zend_is_callable_ex(function_name, NULL, 0, NULL, &fcc, &error)) {
if (error) {
efree(error);