From: George Peter Banyard Date: Wed, 8 Jul 2020 16:36:46 +0000 (+0200) Subject: Use ZPP callable check in zend built in functions X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=7ac9e9bf644ec9a305641386591a507a9159e5be;p=php Use ZPP callable check in zend built in functions --- diff --git a/Zend/tests/exception_handler_004.phpt b/Zend/tests/exception_handler_004.phpt index f07970d337..6935c2744a 100644 --- a/Zend/tests/exception_handler_004.phpt +++ b/Zend/tests/exception_handler_004.phpt @@ -16,5 +16,5 @@ try { ?> --EXPECT-- -set_exception_handler(): Argument #1 ($exception_handler) must be a valid callback -set_exception_handler(): Argument #1 ($exception_handler) must be a valid callback +set_exception_handler(): Argument #1 ($exception_handler) must be a valid callback or null, function 'fo' not found or invalid function name +set_exception_handler(): Argument #1 ($exception_handler) must be a valid callback or null, class '' not found diff --git a/Zend/tests/exception_handler_007.phpt b/Zend/tests/exception_handler_007.phpt new file mode 100644 index 0000000000..757154dde5 --- /dev/null +++ b/Zend/tests/exception_handler_007.phpt @@ -0,0 +1,26 @@ +--TEST-- +exception handler tests - 7 +--FILE-- + +--EXPECTF-- +Fatal error: Uncaught Exception in %s:%d +Stack trace: +#0 {main} + thrown in %s on line %d diff --git a/Zend/zend_builtin_functions.c b/Zend/zend_builtin_functions.c index f766227343..4a3c2f4bbf 100644 --- a/Zend/zend_builtin_functions.c +++ b/Zend/zend_builtin_functions.c @@ -1179,22 +1179,15 @@ ZEND_FUNCTION(trigger_error) /* {{{ Sets a user-defined error handler function. Returns the previously defined error handler, or false on error */ ZEND_FUNCTION(set_error_handler) { - zval *error_handler; + zend_fcall_info fci; + zend_fcall_info_cache fcc; zend_long error_type = E_ALL; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "z|l", &error_handler, &error_type) == FAILURE) { + /* callable argument corresponds to the error handler */ + if (zend_parse_parameters(ZEND_NUM_ARGS(), "f!|l", &fci, &fcc, &error_type) == FAILURE) { RETURN_THROWS(); } - if (Z_TYPE_P(error_handler) != IS_NULL) { /* NULL == unset */ - if (!zend_is_callable(error_handler, 0, NULL)) { - zend_string *error_handler_name = zend_get_callable_name(error_handler); - zend_argument_type_error(1, "must be a valid callback"); - zend_string_release_ex(error_handler_name, 0); - RETURN_THROWS(); - } - } - if (Z_TYPE(EG(user_error_handler)) != IS_UNDEF) { ZVAL_COPY(return_value, &EG(user_error_handler)); } @@ -1202,12 +1195,12 @@ ZEND_FUNCTION(set_error_handler) zend_stack_push(&EG(user_error_handlers_error_reporting), &EG(user_error_handler_error_reporting)); zend_stack_push(&EG(user_error_handlers), &EG(user_error_handler)); - if (Z_TYPE_P(error_handler) == IS_NULL) { /* unset user-defined handler */ + if (!ZEND_FCI_INITIALIZED(fci)) { /* unset user-defined handler */ ZVAL_UNDEF(&EG(user_error_handler)); return; } - ZVAL_COPY(&EG(user_error_handler), error_handler); + ZVAL_COPY(&EG(user_error_handler), &(fci.function_name)); EG(user_error_handler_error_reporting) = (int)error_type; } /* }}} */ @@ -1244,33 +1237,26 @@ ZEND_FUNCTION(restore_error_handler) /* {{{ Sets a user-defined exception handler function. Returns the previously defined exception handler, or false on error */ ZEND_FUNCTION(set_exception_handler) { - zval *exception_handler; + zend_fcall_info fci; + zend_fcall_info_cache fcc; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &exception_handler) == FAILURE) { + /* callable argument corresponds to the exception handler */ + if (zend_parse_parameters(ZEND_NUM_ARGS(), "f!", &fci, &fcc) == FAILURE) { RETURN_THROWS(); } - if (Z_TYPE_P(exception_handler) != IS_NULL) { /* NULL == unset */ - if (!zend_is_callable(exception_handler, 0, NULL)) { - zend_string *exception_handler_name = zend_get_callable_name(exception_handler); - zend_argument_type_error(1, "must be a valid callback"); - zend_string_release_ex(exception_handler_name, 0); - RETURN_THROWS(); - } - } - if (Z_TYPE(EG(user_exception_handler)) != IS_UNDEF) { ZVAL_COPY(return_value, &EG(user_exception_handler)); } zend_stack_push(&EG(user_exception_handlers), &EG(user_exception_handler)); - if (Z_TYPE_P(exception_handler) == IS_NULL) { /* unset user-defined handler */ + if (!ZEND_FCI_INITIALIZED(fci)) { /* unset user-defined handler */ ZVAL_UNDEF(&EG(user_exception_handler)); return; } - ZVAL_COPY(&EG(user_exception_handler), exception_handler); + ZVAL_COPY(&EG(user_exception_handler), &(fci.function_name)); } /* }}} */ diff --git a/Zend/zend_builtin_functions.stub.php b/Zend/zend_builtin_functions.stub.php index 18b64bfa03..8e1bb0b94c 100644 --- a/Zend/zend_builtin_functions.stub.php +++ b/Zend/zend_builtin_functions.stub.php @@ -69,12 +69,12 @@ function trigger_error(string $message, int $error_type = E_USER_NOTICE): bool { function user_error(string $message, int $error_type = E_USER_NOTICE): bool {} /** @return string|array|object|null */ -function set_error_handler($error_handler, int $error_types = E_ALL) {} +function set_error_handler(?callable $error_handler, int $error_types = E_ALL) {} function restore_error_handler(): bool {} /** @return string|array|object|null */ -function set_exception_handler($exception_handler) {} +function set_exception_handler(?callable $exception_handler) {} function restore_exception_handler(): bool {} diff --git a/Zend/zend_builtin_functions_arginfo.h b/Zend/zend_builtin_functions_arginfo.h index 1964c121c9..1fa189410c 100644 --- a/Zend/zend_builtin_functions_arginfo.h +++ b/Zend/zend_builtin_functions_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: f81f2b4cf552c4ee8406b91c437797feb1164be0 */ + * Stub hash: 0d3c035fc2b9f0dcdbf6efe3c740d8aa3805ec32 */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_zend_version, 0, 0, IS_STRING, 0) ZEND_END_ARG_INFO() @@ -127,7 +127,7 @@ ZEND_END_ARG_INFO() #define arginfo_user_error arginfo_trigger_error ZEND_BEGIN_ARG_INFO_EX(arginfo_set_error_handler, 0, 0, 1) - ZEND_ARG_INFO(0, error_handler) + ZEND_ARG_TYPE_INFO(0, error_handler, IS_CALLABLE, 1) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, error_types, IS_LONG, 0, "E_ALL") ZEND_END_ARG_INFO() @@ -135,7 +135,7 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_restore_error_handler, 0, 0, _IS ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_set_exception_handler, 0, 0, 1) - ZEND_ARG_INFO(0, exception_handler) + ZEND_ARG_TYPE_INFO(0, exception_handler, IS_CALLABLE, 1) ZEND_END_ARG_INFO() #define arginfo_restore_exception_handler arginfo_restore_error_handler