diff --git a/Zend/tests/bug69315.phpt b/Zend/tests/bug69315.phpt index 0eb5afb0808ab..82017c0552410 100644 --- a/Zend/tests/bug69315.phpt +++ b/Zend/tests/bug69315.phpt @@ -7,32 +7,44 @@ disable_functions=strlen,defined,call_user_func,constant,is_string var_dump(function_exists("strlen")); var_dump(is_callable("strlen")); -var_dump(strlen("xxx")); -var_dump(defined("PHP_VERSION")); -var_dump(constant("PHP_VERSION")); -var_dump(call_user_func("strlen")); -var_dump(is_string("xxx")); -var_dump(is_string()); +try { + var_dump(strlen("xxx")); +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} +try { + var_dump(defined("PHP_VERSION")); +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} +try { + var_dump(constant("PHP_VERSION")); +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} +try { + var_dump(call_user_func("strlen")); +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} +try { + var_dump(is_string("xxx")); +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} +try { + var_dump(is_string()); +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} ?> ---EXPECTF-- +--EXPECT-- bool(false) -bool(true) - -Warning: strlen() has been disabled for security reasons in %sbug69315.php on line %d -NULL - -Warning: defined() has been disabled for security reasons in %sbug69315.php on line %d -NULL - -Warning: constant() has been disabled for security reasons in %sbug69315.php on line %d -NULL - -Warning: call_user_func() has been disabled for security reasons in %sbug69315.php on line %d -NULL - -Warning: is_string() has been disabled for security reasons in %sbug69315.php on line %d -NULL - -Warning: is_string() has been disabled for security reasons in %s on line %d -NULL +bool(false) +Call to undefined function strlen() +Call to undefined function defined() +Call to undefined function constant() +Call to undefined function call_user_func() +Call to undefined function is_string() +Call to undefined function is_string() diff --git a/Zend/tests/bug79382.phpt b/Zend/tests/bug79382.phpt new file mode 100644 index 0000000000000..bc6099c4e4329 --- /dev/null +++ b/Zend/tests/bug79382.phpt @@ -0,0 +1,18 @@ +--TEST-- +Bug #79382: Cannot redeclare disabled function +--INI-- +disable_functions=strlen +--FILE-- + +--EXPECT-- +int(6) diff --git a/Zend/tests/errmsg_020.phpt b/Zend/tests/errmsg_020.phpt index 636e29d01fe31..4a7c326d05317 100644 --- a/Zend/tests/errmsg_020.phpt +++ b/Zend/tests/errmsg_020.phpt @@ -5,10 +5,12 @@ disable_functions=phpinfo --FILE-- getMessage(), "\n"; +} -echo "Done\n"; ?> ---EXPECTF-- -Warning: phpinfo() has been disabled for security reasons in %s on line %d -Done +--EXPECT-- +Call to undefined function phpinfo() diff --git a/Zend/zend_API.c b/Zend/zend_API.c index 4aa76ca111036..b91441687f8e7 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -2686,27 +2686,9 @@ ZEND_API int zend_set_hash_symbol(zval *symbol, const char *name, int name_lengt /* Disabled functions support */ -/* {{{ proto void display_disabled_function(void) -Dummy function which displays an error when a disabled function is called. */ -ZEND_API ZEND_COLD ZEND_FUNCTION(display_disabled_function) -{ - zend_error(E_WARNING, "%s() has been disabled for security reasons", get_active_function_name()); -} -/* }}} */ - ZEND_API int zend_disable_function(char *function_name, size_t function_name_length) /* {{{ */ { - zend_internal_function *func; - if ((func = zend_hash_str_find_ptr(CG(function_table), function_name, function_name_length))) { - zend_free_internal_arg_info(func); - func->fn_flags &= ~(ZEND_ACC_VARIADIC | ZEND_ACC_HAS_TYPE_HINTS | ZEND_ACC_HAS_RETURN_TYPE); - func->num_args = 0; - func->required_num_args = 0; - func->arg_info = NULL; - func->handler = ZEND_FN(display_disabled_function); - return SUCCESS; - } - return FAILURE; + return zend_hash_str_del(CG(function_table), function_name, function_name_length); } /* }}} */ diff --git a/Zend/zend_API.h b/Zend/zend_API.h index 51353ad710c15..fe6ec000e9d08 100644 --- a/Zend/zend_API.h +++ b/Zend/zend_API.h @@ -593,8 +593,6 @@ ZEND_API zend_bool zend_is_iterable(zval *iterable); ZEND_API zend_bool zend_is_countable(zval *countable); -ZEND_API ZEND_FUNCTION(display_disabled_function); - ZEND_API int zend_get_default_from_internal_arg_info( zval *default_value_zval, zend_internal_arg_info *arg_info); diff --git a/Zend/zend_builtin_functions.c b/Zend/zend_builtin_functions.c index 5682d02822f90..300adf400e1d9 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)); } diff --git a/Zend/zend_builtin_functions.stub.php b/Zend/zend_builtin_functions.stub.php index ec3d5a5203d8a..43b55b42a7d3b 100644 --- a/Zend/zend_builtin_functions.stub.php +++ b/Zend/zend_builtin_functions.stub.php @@ -85,7 +85,7 @@ function get_declared_traits(): array {} function get_declared_interfaces(): array {} -function get_defined_functions(bool $exclude_disabled = false): array {} +function get_defined_functions(bool $exclude_disabled = true): array {} function get_defined_vars(): array {} diff --git a/Zend/zend_builtin_functions_arginfo.h b/Zend/zend_builtin_functions_arginfo.h index ab4510f3d8ee5..571b14ba728ff 100644 --- a/Zend/zend_builtin_functions_arginfo.h +++ b/Zend/zend_builtin_functions_arginfo.h @@ -146,7 +146,7 @@ ZEND_END_ARG_INFO() #define arginfo_get_declared_interfaces arginfo_func_get_args ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_get_defined_functions, 0, 0, IS_ARRAY, 0) - ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, exclude_disabled, _IS_BOOL, 0, "false") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, exclude_disabled, _IS_BOOL, 0, "true") ZEND_END_ARG_INFO() #define arginfo_get_defined_vars arginfo_func_get_args diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 7c84456a6ff9c..197d9aa7e6027 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -3934,10 +3934,6 @@ int zend_compile_func_array_slice(znode *result, zend_ast_list *args) /* {{{ */ int zend_try_compile_special_func(znode *result, zend_string *lcname, zend_ast_list *args, zend_function *fbc, uint32_t type) /* {{{ */ { - if (fbc->internal_function.handler == ZEND_FN(display_disabled_function)) { - return FAILURE; - } - if (CG(compiler_options) & ZEND_COMPILE_NO_BUILTINS) { return FAILURE; } diff --git a/ext/opcache/Optimizer/pass1.c b/ext/opcache/Optimizer/pass1.c index 9219e5e19e62b..3beb1788a3e76 100644 --- a/ext/opcache/Optimizer/pass1.c +++ b/ext/opcache/Optimizer/pass1.c @@ -382,12 +382,10 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx) Z_TYPE(ZEND_OP1_LITERAL(send1_opline)) == IS_STRING) { if ((Z_STRLEN(ZEND_OP2_LITERAL(init_opline)) == sizeof("function_exists")-1 && !memcmp(Z_STRVAL(ZEND_OP2_LITERAL(init_opline)), - "function_exists", sizeof("function_exists")-1) && - !zend_optimizer_is_disabled_func("function_exists", sizeof("function_exists") - 1)) || + "function_exists", sizeof("function_exists")-1)) || (Z_STRLEN(ZEND_OP2_LITERAL(init_opline)) == sizeof("is_callable")-1 && !memcmp(Z_STRVAL(ZEND_OP2_LITERAL(init_opline)), - "is_callable", sizeof("is_callable")) && - !zend_optimizer_is_disabled_func("is_callable", sizeof("is_callable") - 1))) { + "is_callable", sizeof("is_callable")))) { zend_internal_function *func; zend_string *lc_name = zend_string_tolower( Z_STR(ZEND_OP1_LITERAL(send1_opline))); @@ -400,12 +398,7 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx) #endif ) { zval t; - if (Z_STRLEN(ZEND_OP2_LITERAL(init_opline)) == sizeof("is_callable") - 1 || - func->handler != ZEND_FN(display_disabled_function)) { - ZVAL_TRUE(&t); - } else { - ZVAL_FALSE(&t); - } + ZVAL_TRUE(&t); literal_dtor(&ZEND_OP2_LITERAL(init_opline)); MAKE_NOP(init_opline); literal_dtor(&ZEND_OP1_LITERAL(send1_opline)); @@ -423,8 +416,7 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx) break; } else if (Z_STRLEN(ZEND_OP2_LITERAL(init_opline)) == sizeof("extension_loaded")-1 && !memcmp(Z_STRVAL(ZEND_OP2_LITERAL(init_opline)), - "extension_loaded", sizeof("extension_loaded")-1) && - !zend_optimizer_is_disabled_func("extension_loaded", sizeof("extension_loaded") - 1)) { + "extension_loaded", sizeof("extension_loaded")-1)) { zval t; zend_string *lc_name = zend_string_tolower( Z_STR(ZEND_OP1_LITERAL(send1_opline))); @@ -465,8 +457,7 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx) break; } else if (Z_STRLEN(ZEND_OP2_LITERAL(init_opline)) == sizeof("constant")-1 && !memcmp(Z_STRVAL(ZEND_OP2_LITERAL(init_opline)), - "constant", sizeof("constant")-1) && - !zend_optimizer_is_disabled_func("constant", sizeof("constant") - 1)) { + "constant", sizeof("constant")-1)) { zval t; if (zend_optimizer_get_persistent_constant(Z_STR(ZEND_OP1_LITERAL(send1_opline)), &t, 1)) { @@ -488,7 +479,6 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx) } else if (Z_STRLEN(ZEND_OP2_LITERAL(init_opline)) == sizeof("dirname")-1 && !memcmp(Z_STRVAL(ZEND_OP2_LITERAL(init_opline)), "dirname", sizeof("dirname") - 1) && - !zend_optimizer_is_disabled_func("dirname", sizeof("dirname") - 1) && IS_ABSOLUTE_PATH(Z_STRVAL(ZEND_OP1_LITERAL(send1_opline)), Z_STRLEN(ZEND_OP1_LITERAL(send1_opline)))) { zend_string *dirname = zend_string_init(Z_STRVAL(ZEND_OP1_LITERAL(send1_opline)), Z_STRLEN(ZEND_OP1_LITERAL(send1_opline)), 0); ZSTR_LEN(dirname) = zend_dirname(ZSTR_VAL(dirname), ZSTR_LEN(dirname)); diff --git a/ext/opcache/Optimizer/sccp.c b/ext/opcache/Optimizer/sccp.c index d5c27ca664c45..adea2187785c6 100644 --- a/ext/opcache/Optimizer/sccp.c +++ b/ext/opcache/Optimizer/sccp.c @@ -1019,8 +1019,7 @@ static inline int ct_eval_func_call( } func = zend_hash_find_ptr(CG(function_table), name); - if (!func || func->type != ZEND_INTERNAL_FUNCTION - || func->internal_function.handler == ZEND_FN(display_disabled_function)) { + if (!func || func->type != ZEND_INTERNAL_FUNCTION) { return FAILURE; } diff --git a/ext/opcache/Optimizer/zend_func_info.c b/ext/opcache/Optimizer/zend_func_info.c index 6f1c24705171e..ff29cce9896a8 100644 --- a/ext/opcache/Optimizer/zend_func_info.c +++ b/ext/opcache/Optimizer/zend_func_info.c @@ -899,9 +899,7 @@ static uint32_t get_internal_func_info( } func_info_t *info = Z_PTR_P(zv); - if (UNEXPECTED(zend_optimizer_is_disabled_func(info->name, info->name_len))) { - return MAY_BE_NULL; - } else if (info->info_func) { + if (info->info_func) { return info->info_func(call_info, ssa); } else { return info->info; diff --git a/ext/opcache/Optimizer/zend_optimizer.c b/ext/opcache/Optimizer/zend_optimizer.c index 6f896af27ce41..61d2750ce9f89 100644 --- a/ext/opcache/Optimizer/zend_optimizer.c +++ b/ext/opcache/Optimizer/zend_optimizer.c @@ -157,13 +157,6 @@ static inline int zend_optimizer_add_literal_string(zend_op_array *op_array, zen return zend_optimizer_add_literal(op_array, &zv); } -int zend_optimizer_is_disabled_func(const char *name, size_t len) { - zend_function *fbc = (zend_function *)zend_hash_str_find_ptr(EG(function_table), name, len); - - return (fbc && fbc->type == ZEND_INTERNAL_FUNCTION && - fbc->internal_function.handler == ZEND_FN(display_disabled_function)); -} - static inline void drop_leading_backslash(zval *val) { if (Z_STRVAL_P(val)[0] == '\\') { zend_string *str = zend_string_init(Z_STRVAL_P(val) + 1, Z_STRLEN_P(val) - 1, 0); diff --git a/ext/opcache/Optimizer/zend_optimizer_internal.h b/ext/opcache/Optimizer/zend_optimizer_internal.h index ed0dac3e1921d..a525b668bfd0e 100644 --- a/ext/opcache/Optimizer/zend_optimizer_internal.h +++ b/ext/opcache/Optimizer/zend_optimizer_internal.h @@ -108,7 +108,6 @@ void zend_optimize_temporary_variables(zend_op_array *op_array, zend_optimizer_c void zend_optimizer_nop_removal(zend_op_array *op_array, zend_optimizer_ctx *ctx); void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx *ctx); void zend_optimizer_compact_vars(zend_op_array *op_array); -int zend_optimizer_is_disabled_func(const char *name, size_t len); zend_function *zend_optimizer_get_called_func( zend_script *script, zend_op_array *op_array, zend_op *opline, zend_bool *is_prototype); uint32_t zend_optimizer_classify_function(zend_string *name, uint32_t num_args); diff --git a/ext/opcache/tests/bug68104.phpt b/ext/opcache/tests/bug68104.phpt index 8d3bf70a4d069..6d994c79afe09 100644 --- a/ext/opcache/tests/bug68104.phpt +++ b/ext/opcache/tests/bug68104.phpt @@ -11,9 +11,12 @@ disable_functions=dl --FILE-- getMessage(), "\n"; +} ?> ---EXPECTF-- -bool(true) - -Warning: dl() has been disabled for security reasons in %sbug68104.php on line %d +--EXPECT-- +bool(false) +Call to undefined function dl() diff --git a/ext/opcache/tests/bug76796.phpt b/ext/opcache/tests/bug76796.phpt index ba7e26a0d5dc3..18f25d2558907 100644 --- a/ext/opcache/tests/bug76796.phpt +++ b/ext/opcache/tests/bug76796.phpt @@ -10,9 +10,12 @@ disable_functions=strpos --FILE-- getMessage(), "\n"; +} ?> ---EXPECTF-- -Warning: strpos() has been disabled for security reasons in %s on line %d -NULL +--EXPECT-- +Call to undefined function strpos() diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index 552913dd1ef02..2856e0c6db77f 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -1549,16 +1549,12 @@ ZEND_METHOD(ReflectionFunctionAbstract, isUserDefined) Returns whether this function has been disabled or not */ ZEND_METHOD(ReflectionFunction, isDisabled) { - reflection_object *intern; - zend_function *fptr; - - GET_REFLECTION_OBJECT_PTR(fptr); - if (zend_parse_parameters_none() == FAILURE) { RETURN_THROWS(); } - RETURN_BOOL(fptr->type == ZEND_INTERNAL_FUNCTION && fptr->internal_function.handler == zif_display_disabled_function); + /* A disabled function cannot be queried using Reflection. */ + RETURN_FALSE; } /* }}} */ diff --git a/ext/reflection/php_reflection.stub.php b/ext/reflection/php_reflection.stub.php index be6269fe78ba1..0adce7921c573 100644 --- a/ext/reflection/php_reflection.stub.php +++ b/ext/reflection/php_reflection.stub.php @@ -104,7 +104,10 @@ public function __construct($name) {} public function __toString(): string {} - /** @return bool */ + /** + * @return bool + * @deprecated ReflectionFunction can no longer be constructed for disabled functions + */ public function isDisabled() {} /** @return mixed */ diff --git a/ext/reflection/php_reflection_arginfo.h b/ext/reflection/php_reflection_arginfo.h index a0a606295b7ac..a7f12dba8ca1f 100644 --- a/ext/reflection/php_reflection_arginfo.h +++ b/ext/reflection/php_reflection_arginfo.h @@ -694,7 +694,7 @@ static const zend_function_entry class_ReflectionFunctionAbstract_methods[] = { static const zend_function_entry class_ReflectionFunction_methods[] = { ZEND_ME(ReflectionFunction, __construct, arginfo_class_ReflectionFunction___construct, ZEND_ACC_PUBLIC) ZEND_ME(ReflectionFunction, __toString, arginfo_class_ReflectionFunction___toString, ZEND_ACC_PUBLIC) - ZEND_ME(ReflectionFunction, isDisabled, arginfo_class_ReflectionFunction_isDisabled, ZEND_ACC_PUBLIC) + ZEND_ME(ReflectionFunction, isDisabled, arginfo_class_ReflectionFunction_isDisabled, ZEND_ACC_PUBLIC|ZEND_ACC_DEPRECATED) ZEND_ME(ReflectionFunction, invoke, arginfo_class_ReflectionFunction_invoke, ZEND_ACC_PUBLIC) ZEND_ME(ReflectionFunction, invokeArgs, arginfo_class_ReflectionFunction_invokeArgs, ZEND_ACC_PUBLIC) ZEND_ME(ReflectionFunction, getClosure, arginfo_class_ReflectionFunction_getClosure, ZEND_ACC_PUBLIC) diff --git a/ext/reflection/tests/ReflectionFunction_isDisabled_basic.phpt b/ext/reflection/tests/ReflectionFunction_isDisabled_basic.phpt index 220c16f9cb10a..d63492751655e 100644 --- a/ext/reflection/tests/ReflectionFunction_isDisabled_basic.phpt +++ b/ext/reflection/tests/ReflectionFunction_isDisabled_basic.phpt @@ -7,8 +7,18 @@ TestFest PHP|Tek disable_functions=is_file --FILE-- isDisabled()); +try { + $rf = new ReflectionFunction('is_file'); + var_dump($rf->isDisabled()); +} catch (ReflectionException $e) { + echo $e->getMessage(), "\n"; +} + +$rf = new ReflectionFunction('is_string'); +var_dump($rf->isDisabled()); ?> ---EXPECT-- -bool(true) +--EXPECTF-- +Function is_file() does not exist + +Deprecated: Function ReflectionFunction::isDisabled() is deprecated in %s on line %d +bool(false) diff --git a/tests/basic/bug31875.phpt b/tests/basic/bug31875.phpt index 65f68b9af3b8a..c8ad25ec9f62c 100644 --- a/tests/basic/bug31875.phpt +++ b/tests/basic/bug31875.phpt @@ -8,6 +8,8 @@ disable_functions=dl ---EXPECT-- -bool(true) -bool(true) +--EXPECTF-- +bool(false) + +Deprecated: get_defined_functions(): Setting $exclude_disabled to false has no effect in %s on line %d +bool(false) bool(false)