summaryrefslogtreecommitdiff
path: root/Zend/zend_builtin_functions.c
diff options
context:
space:
mode:
authorNikita Popov <nikita.ppv@gmail.com>2020-04-27 13:17:37 +0200
committerNikita Popov <nikita.ppv@gmail.com>2020-04-30 09:53:57 +0200
commit53eee290b6f5ca531aef19885a392c939013ce36 (patch)
tree1eac8e854e60f39bd3432f92a603f9f0b9d41169 /Zend/zend_builtin_functions.c
parent8cb237345a50f724aca35133da7155b6bc47d133 (diff)
downloadphp-git-53eee290b6f5ca531aef19885a392c939013ce36.tar.gz
Completely remove disabled functions from function table
Currently, disabling a function only replaces the internal function handler with one that throws a warning, and a few places in the engine special-case such functions, such as function_exists. This leaves us with a Schrödinger's function, which both does not exist (function_exists returns false) and does exist (you cannot define a function with the same name). In particular, this prevents the implementation of robust polyfills, as reported in https://bugs.php.net/bug.php?id=79382: if (!function_exists('getallheaders')) { function getallheaders(...) { ... } } If getallheaders() is a disabled function, this code will break. This patch changes disable_functions to remove the functions from the function table completely. For all intents and purposes, it will look like the function does not exist. This also renders two bits of PHP functionality obsolete and thus deprecated: * ReflectionFunction::isDisabled(), as it will no longer be possible to construct the ReflectionFunction of a disabled function in the first place. * get_defined_functions() with $exclude_disabled=false, as get_defined_functions() now never returns disabled functions. Fixed bug #79382. Closes GH-5473.
Diffstat (limited to 'Zend/zend_builtin_functions.c')
-rw-r--r--Zend/zend_builtin_functions.c30
1 files changed, 10 insertions, 20 deletions
diff --git a/Zend/zend_builtin_functions.c b/Zend/zend_builtin_functions.c
index 5682d02822..300adf400e 100644
--- a/Zend/zend_builtin_functions.c
+++ b/Zend/zend_builtin_functions.c
@@ -1127,7 +1127,7 @@ ZEND_FUNCTION(trait_exists)
ZEND_FUNCTION(function_exists)
{
zend_string *name;
- zend_function *func;
+ zend_bool exists;
zend_string *lcname;
ZEND_PARSE_PARAMETERS_START(1, 1)
@@ -1142,15 +1142,10 @@ ZEND_FUNCTION(function_exists)
lcname = zend_string_tolower(name);
}
- func = zend_hash_find_ptr(EG(function_table), lcname);
+ exists = zend_hash_exists(EG(function_table), lcname);
zend_string_release_ex(lcname, 0);
- /*
- * A bit of a hack, but not a bad one: we see if the handler of the function
- * is actually one that displays "function is disabled" message.
- */
- RETURN_BOOL(func && (func->type != ZEND_INTERNAL_FUNCTION ||
- func->internal_function.handler != zif_display_disabled_function));
+ RETURN_BOOL(exists);
}
/* }}} */
@@ -1420,30 +1415,25 @@ ZEND_FUNCTION(get_defined_functions)
zval internal, user;
zend_string *key;
zend_function *func;
- zend_bool exclude_disabled = 0;
- char *disable_functions = NULL;
+ zend_bool exclude_disabled = 1;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "|b", &exclude_disabled) == FAILURE) {
RETURN_THROWS();
}
+ if (exclude_disabled == 0) {
+ zend_error(E_DEPRECATED,
+ "get_defined_functions(): Setting $exclude_disabled to false has no effect");
+ }
+
array_init(&internal);
array_init(&user);
array_init(return_value);
- if (exclude_disabled) {
- disable_functions = INI_STR("disable_functions");
- }
ZEND_HASH_FOREACH_STR_KEY_PTR(EG(function_table), key, func) {
if (key && ZSTR_VAL(key)[0] != 0) {
if (func->type == ZEND_INTERNAL_FUNCTION) {
- if (disable_functions != NULL) {
- if (strstr(disable_functions, func->common.function_name->val) == NULL) {
- add_next_index_str(&internal, zend_string_copy(key));
- }
- } else {
- add_next_index_str(&internal, zend_string_copy(key));
- }
+ add_next_index_str(&internal, zend_string_copy(key));
} else if (func->type == ZEND_USER_FUNCTION) {
add_next_index_str(&user, zend_string_copy(key));
}