]> granicus.if.org Git - php/commitdiff
Unwrap reference returns in cufa etc
authorNikita Popov <nikic@php.net>
Fri, 30 Sep 2016 20:08:08 +0000 (22:08 +0200)
committerNikita Popov <nikic@php.net>
Fri, 30 Sep 2016 20:10:01 +0000 (22:10 +0200)
Zend/tests/dynamic_call_to_ref_returning_function.phpt [new file with mode: 0644]
Zend/zend_closures.c
ext/reflection/php_reflection.c
ext/standard/basic_functions.c

diff --git a/Zend/tests/dynamic_call_to_ref_returning_function.phpt b/Zend/tests/dynamic_call_to_ref_returning_function.phpt
new file mode 100644 (file)
index 0000000..c4b6a9b
--- /dev/null
@@ -0,0 +1,39 @@
+--TEST--
+When performing a dynamic call to a ret-by-ref function, the reference should be unwrapped
+--FILE--
+<?php
+
+namespace Foo;
+
+function &retRef($x) {
+    return $x;
+}
+
+var_dump(call_user_func('Foo\retRef', 42));
+var_dump(call_user_func_array('Foo\retRef', [42]));
+
+$closure = function &($x) {
+    return $x;
+};
+var_dump($closure->call(new class {}, 42));
+
+var_dump((new \ReflectionFunction('Foo\retRef'))->invoke(42));
+var_dump((new \ReflectionFunction('Foo\retRef'))->invokeArgs([42]));
+
+class Bar {
+    function &method($x) {
+        return $x;
+    }
+}
+var_dump((new \ReflectionMethod('Foo\Bar', 'method'))->invoke(new Bar, 42));
+var_dump((new \ReflectionMethod('Foo\Bar', 'method'))->invokeArgs(new Bar, [42]));
+
+?>
+--EXPECT--
+int(42)
+int(42)
+int(42)
+int(42)
+int(42)
+int(42)
+int(42)
index bedf022a4b416346c9b8db5bfc218c940da3821c..eb726484f569f4444a4851c250393f5fe72231f8 100644 (file)
@@ -166,6 +166,9 @@ ZEND_METHOD(Closure, call)
        }
 
        if (zend_call_function(&fci, &fci_cache) == SUCCESS && Z_TYPE(closure_result) != IS_UNDEF) {
+               if (Z_ISREF(closure_result)) {
+                       zend_unwrap_reference(&closure_result);
+               }
                ZVAL_COPY_VALUE(return_value, &closure_result);
        }
 
index 52d35409d3f5cf5bbd405e7bdffb0bc11eaf817e..9ecb04d461f387818afef7ec3d43e0b9f63f8e60 100644 (file)
@@ -1985,6 +1985,9 @@ ZEND_METHOD(reflection_function, invoke)
        }
 
        if (Z_TYPE(retval) != IS_UNDEF) {
+               if (Z_ISREF(retval)) {
+                       zend_unwrap_reference(&retval);
+               }
                ZVAL_COPY_VALUE(return_value, &retval);
        }
 }
@@ -2048,6 +2051,9 @@ ZEND_METHOD(reflection_function, invokeArgs)
        }
 
        if (Z_TYPE(retval) != IS_UNDEF) {
+               if (Z_ISREF(retval)) {
+                       zend_unwrap_reference(&retval);
+               }
                ZVAL_COPY_VALUE(return_value, &retval);
        }
 }
@@ -3323,6 +3329,9 @@ static void reflection_method_invoke(INTERNAL_FUNCTION_PARAMETERS, int variadic)
        }
 
        if (Z_TYPE(retval) != IS_UNDEF) {
+               if (Z_ISREF(retval)) {
+                       zend_unwrap_reference(&retval);
+               }
                ZVAL_COPY_VALUE(return_value, &retval);
        }
 }
index fa90206a45f62697c9ab4f31e540fcad344cc1bd..13e8a4e6eb80e65be06fe3ba75eb531f5ac8ce41 100644 (file)
@@ -4823,6 +4823,9 @@ PHP_FUNCTION(call_user_func)
        fci.retval = &retval;
 
        if (zend_call_function(&fci, &fci_cache) == SUCCESS && Z_TYPE(retval) != IS_UNDEF) {
+               if (Z_ISREF(retval)) {
+                       zend_unwrap_reference(&retval);
+               }
                ZVAL_COPY_VALUE(return_value, &retval);
        }
 }
@@ -4846,6 +4849,9 @@ PHP_FUNCTION(call_user_func_array)
        fci.retval = &retval;
 
        if (zend_call_function(&fci, &fci_cache) == SUCCESS && Z_TYPE(retval) != IS_UNDEF) {
+               if (Z_ISREF(retval)) {
+                       zend_unwrap_reference(&retval);
+               }
                ZVAL_COPY_VALUE(return_value, &retval);
        }
 
@@ -4880,6 +4886,9 @@ PHP_FUNCTION(forward_static_call)
        }
 
        if (zend_call_function(&fci, &fci_cache) == SUCCESS && Z_TYPE(retval) != IS_UNDEF) {
+               if (Z_ISREF(retval)) {
+                       zend_unwrap_reference(&retval);
+               }
                ZVAL_COPY_VALUE(return_value, &retval);
        }
 }
@@ -4908,6 +4917,9 @@ PHP_FUNCTION(forward_static_call_array)
        }
 
        if (zend_call_function(&fci, &fci_cache) == SUCCESS && Z_TYPE(retval) != IS_UNDEF) {
+               if (Z_ISREF(retval)) {
+                       zend_unwrap_reference(&retval);
+               }
                ZVAL_COPY_VALUE(return_value, &retval);
        }