diff options
author | Nikita Popov <nikita.ppv@gmail.com> | 2020-09-04 09:41:27 +0200 |
---|---|---|
committer | Nikita Popov <nikita.ppv@gmail.com> | 2020-09-04 14:23:14 +0200 |
commit | 2e218180efebeac4fe0fe3f36e39fce8fc513468 (patch) | |
tree | 75d028ac345289ff3a0211c146419c50492372c1 /ext/spl/php_spl.c | |
parent | c0d6b05b686767fcf6a858d5c039bee764655590 (diff) | |
download | php-git-2e218180efebeac4fe0fe3f36e39fce8fc513468.tar.gz |
Release call trampolines in zpp fcc
When using zpp 'f' or Z_PARAM_FUNC, if the fcc points to a call
trampoline release it immediately and force zend_call_function
to refetch it. This may require additional callability checks
if __call is used, but avoids the need to carefully free fcc
values in all internal functions -- in some cases this is not
simple, as a type error might be triggered by a later argument
in the same zpp call.
This fixes oss-fuzz #25390.
Closes GH-6073.
Diffstat (limited to 'ext/spl/php_spl.c')
-rw-r--r-- | ext/spl/php_spl.c | 9 |
1 files changed, 8 insertions, 1 deletions
diff --git a/ext/spl/php_spl.c b/ext/spl/php_spl.c index d92f774db4..09c876b45f 100644 --- a/ext/spl/php_spl.c +++ b/ext/spl/php_spl.c @@ -519,6 +519,13 @@ PHP_FUNCTION(spl_autoload_register) /* If first arg is not null */ if (ZEND_FCI_INITIALIZED(fci)) { + if (!fcc.function_handler) { + /* Call trampoline has been cleared by zpp. Refetch it, because we want to deal + * with it outselves. It is important that it is not refetched on every call, + * because calls may occur from different scopes. */ + zend_is_callable_ex(&fci.function_name, NULL, 0, NULL, &fcc, NULL); + } + if (fcc.function_handler->type == ZEND_INTERNAL_FUNCTION && fcc.function_handler->internal_function.handler == zif_spl_autoload_call) { zend_argument_value_error(1, "must not be the spl_autoload_call() function"); @@ -566,7 +573,7 @@ PHP_FUNCTION(spl_autoload_unregister) RETURN_THROWS(); } - if (zend_string_equals_literal( + if (fcc.function_handler && zend_string_equals_literal( fcc.function_handler->common.function_name, "spl_autoload_call")) { /* Don't destroy the hash table, as we might be iterating over it right now. */ zend_hash_clean(SPL_G(autoload_functions)); |