From: Antony Dovgal Date: Tue, 6 Dec 2005 15:17:38 +0000 (+0000) Subject: reimplement php_filter_callback() as exception-safe and without memleaks X-Git-Tag: RELEASE_1_0~4 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=a59ddf0a56095f803dbf2e4659c327f9276ede94;p=php reimplement php_filter_callback() as exception-safe and without memleaks --- diff --git a/ext/filter/callback_filter.c b/ext/filter/callback_filter.c index fe5c1fb39b..c4a40572c9 100644 --- a/ext/filter/callback_filter.c +++ b/ext/filter/callback_filter.c @@ -22,20 +22,41 @@ void php_filter_callback(PHP_INPUT_FILTER_PARAM_DECL) { - char *name; - zval *args[1]; + char *name = NULL; + zval *retval_ptr; + zval ***args; + int status; if (!option_array || !zend_is_callable(option_array, IS_CALLABLE_CHECK_NO_ACCESS, &name)) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "First argument is expected to be a valid callback"); - efree(name); + if (name) { + efree(name); + } zval_dtor(value); Z_TYPE_P(value) = IS_NULL; return; } + efree(name); - args[0] = value; + args = safe_emalloc(sizeof(zval **), 1, 0); + args[0] = &value; + + status = call_user_function_ex(EG(function_table), NULL, option_array, &retval_ptr, 1, args, 0, NULL TSRMLS_CC); - call_user_function(EG(function_table), NULL, option_array, value, 1, args TSRMLS_CC); + if (status == SUCCESS && retval_ptr != NULL) { + zval_dtor(value); + *value = *retval_ptr; + zval_copy_ctor(value); + } + else { + zval_dtor(value); + Z_TYPE_P(value) = IS_NULL; + } + + if (retval_ptr) { + zval_ptr_dtor(&retval_ptr); + } + efree(args); } /*