]> granicus.if.org Git - php/commitdiff
fix #41970 (call_user_func_*() leaks on failure)
authorAntony Dovgal <tony2001@php.net>
Thu, 12 Jul 2007 09:19:04 +0000 (09:19 +0000)
committerAntony Dovgal <tony2001@php.net>
Thu, 12 Jul 2007 09:19:04 +0000 (09:19 +0000)
ext/standard/basic_functions.c
ext/standard/tests/general_functions/bug41970.phpt [new file with mode: 0644]

index fd83b8d1b2947fe2248abc59b7a69b22a193aa25..d90cba247938947f0250d706ef560e52dffd253e 100644 (file)
@@ -5032,7 +5032,7 @@ PHP_FUNCTION(error_get_last)
    Call a user function which is the first parameter */
 PHP_FUNCTION(call_user_func)
 {
-       zval *retval_ptr = return_value;
+       zval *retval_ptr = NULL;
        zend_fcall_info fci;
        zend_fcall_info_cache fci_cache;
 
@@ -5040,13 +5040,12 @@ PHP_FUNCTION(call_user_func)
                return;
        }
 
-       fci.retval_ptr_ptr = return_value_ptr;
+       fci.retval_ptr_ptr = &retval_ptr;
 
        if (zend_call_function(&fci, &fci_cache TSRMLS_CC) == SUCCESS) {
-               zval_ptr_dtor(&retval_ptr);
-       }
-       if (!*return_value_ptr) {
-               ALLOC_INIT_ZVAL(*return_value_ptr);
+               *return_value = **fci.retval_ptr_ptr;
+               zval_copy_ctor(return_value);
+               zval_ptr_dtor(fci.retval_ptr_ptr);
        }
 
        if (fci.params) {
@@ -5059,7 +5058,7 @@ PHP_FUNCTION(call_user_func)
    Call a user function which is the first parameter with the arguments contained in array */
 PHP_FUNCTION(call_user_func_array)
 {
-       zval *params, *retval_ptr = return_value;
+       zval *params, *retval_ptr = NULL;
        zend_fcall_info fci;
        zend_fcall_info_cache fci_cache;
 
@@ -5067,15 +5066,13 @@ PHP_FUNCTION(call_user_func_array)
                return;
        }
 
-       fci.retval_ptr_ptr = return_value_ptr;
-
        zend_fcall_info_args(&fci, params TSRMLS_CC);
+       fci.retval_ptr_ptr = &retval_ptr;
 
        if (zend_call_function(&fci, &fci_cache TSRMLS_CC) == SUCCESS) {
-               zval_ptr_dtor(&retval_ptr);
-       }
-       if (!*return_value_ptr) {
-               ALLOC_INIT_ZVAL(*return_value_ptr);
+               *return_value = **fci.retval_ptr_ptr;
+               zval_copy_ctor(return_value);
+               zval_ptr_dtor(fci.retval_ptr_ptr);
        }
 
        zend_fcall_info_args_clear(&fci, 1);
diff --git a/ext/standard/tests/general_functions/bug41970.phpt b/ext/standard/tests/general_functions/bug41970.phpt
new file mode 100644 (file)
index 0000000..cc942ff
--- /dev/null
@@ -0,0 +1,24 @@
+--TEST--
+Bug #41970 (call_user_func_*() leaks on failure)
+--FILE--
+<?php
+
+$a = array(4,3,2);
+
+var_dump(call_user_func_array("sort", array($a)));
+var_dump(call_user_func_array("strlen", array($a)));
+var_dump(call_user_func("sort", $a));
+var_dump(call_user_func("strlen", $a));
+
+echo "Done\n";
+?>
+--EXPECTF--    
+NULL
+
+Notice: Array to string conversion in %s on line %d
+int(5)
+NULL
+
+Notice: Array to string conversion in %s on line %d
+int(5)
+Done