]> granicus.if.org Git - php/commitdiff
Fixed bug #52940 (call_user_func_array still allows call-time pass-by-reference)...
authorDmitry Stogov <dmitry@php.net>
Fri, 1 Oct 2010 11:53:04 +0000 (11:53 +0000)
committerDmitry Stogov <dmitry@php.net>
Fri, 1 Oct 2010 11:53:04 +0000 (11:53 +0000)
Zend/tests/bug52940.phpt [new file with mode: 0644]
Zend/zend_execute_API.c
ext/standard/tests/array/array_map_variation19.phpt
ext/standard/tests/general_functions/call_user_func_array_variation_001.phpt

diff --git a/Zend/tests/bug52940.phpt b/Zend/tests/bug52940.phpt
new file mode 100644 (file)
index 0000000..f8d31c0
--- /dev/null
@@ -0,0 +1,23 @@
+--TEST--
+Bug #52940 (call_user_func_array still allows call-time pass-by-reference)
+--FILE--
+<?php
+function foo($a) {
+       $a++;
+       var_dump($a);   
+}
+function bar(&$a) {
+        $a++;
+        var_dump($a);
+}
+$a = 1;
+call_user_func_array("foo", array(&$a));
+var_dump($a);
+call_user_func_array("bar", array(&$a));
+var_dump($a);
+?>
+--EXPECT--
+int(2)
+int(1)
+int(2)
+int(2)
index f9c9bce99f2cb963fc4023f89c86f2c6c5a54b5c..1f1a2b13d9396e24f74974a54a0f7c45eb8fde44 100644 (file)
@@ -850,17 +850,8 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS
        for (i=0; i<fci->param_count; i++) {
                zval *param;
 
-               if (EX(function_state).function->type == ZEND_INTERNAL_FUNCTION 
-                       && (EX(function_state).function->common.fn_flags & ZEND_ACC_CALL_VIA_HANDLER) == 0 
-                       && !ARG_SHOULD_BE_SENT_BY_REF(EX(function_state).function, i + 1)
-                       && PZVAL_IS_REF(*fci->params[i])) {
-                       SEPARATE_ZVAL(fci->params[i]);
-               }
-
-               if (ARG_SHOULD_BE_SENT_BY_REF(EX(function_state).function, i + 1)
-                       && !PZVAL_IS_REF(*fci->params[i])) {
-
-                       if (Z_REFCOUNT_PP(fci->params[i]) > 1) {
+               if (ARG_SHOULD_BE_SENT_BY_REF(EX(function_state).function, i + 1)) {
+                       if (!PZVAL_IS_REF(*fci->params[i]) && Z_REFCOUNT_PP(fci->params[i]) > 1) {
                                zval *new_zval;
 
                                if (fci->no_separation) {
@@ -888,6 +879,13 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS
                        Z_ADDREF_PP(fci->params[i]);
                        Z_SET_ISREF_PP(fci->params[i]);
                        param = *fci->params[i];
+               } else if (PZVAL_IS_REF(*fci->params[i]) &&
+                          /* don't separate references for __call */
+                          (EX(function_state).function->common.fn_flags & ZEND_ACC_CALL_VIA_HANDLER) == 0 ) {
+                       ALLOC_ZVAL(param);
+                       *param = **(fci->params[i]);
+                       INIT_PZVAL(param);
+                       zval_copy_ctor(param);
                } else if (*fci->params[i] != &EG(uninitialized_zval)) {
                        Z_ADDREF_PP(fci->params[i]);
                        param = *fci->params[i];
index 9478f70eff52f96c5e9ee74de5f594484a0a7a29..0e56428a035b281415e711ec257c55b63a7d0672 100644 (file)
@@ -34,7 +34,7 @@ array(2) {
 }
 array(2) {
   [0]=>
-  &string(7) "changed"
+  &string(10) "original.0"
   [1]=>
   string(10) "original.1"
 }
\ No newline at end of file
index 340e4e5dafa018c683173c5762f0175c0e3ad1b9..c05a329342436e5e892826a3e56d47278a17067f 100644 (file)
@@ -50,7 +50,7 @@ array(1) {
 ------ Calling by_val() with referenced argument ------
 array(1) {
   [0]=>
-  &string(7) "changed"
+  &string(8) "original"
 }
 ------ Calling by_ref() with referenced argument ------
 array(1) {