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;
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) {
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;
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);
--- /dev/null
+--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