Skip to content

Commit 3ea392e

Browse files
committed
Completely remove disabled functions
1 parent a447897 commit 3ea392e

19 files changed

+108
-126
lines changed

Zend/tests/bug69315.phpt

Lines changed: 38 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -7,32 +7,44 @@ disable_functions=strlen,defined,call_user_func,constant,is_string
77

88
var_dump(function_exists("strlen"));
99
var_dump(is_callable("strlen"));
10-
var_dump(strlen("xxx"));
11-
var_dump(defined("PHP_VERSION"));
12-
var_dump(constant("PHP_VERSION"));
13-
var_dump(call_user_func("strlen"));
14-
var_dump(is_string("xxx"));
15-
var_dump(is_string());
10+
try {
11+
var_dump(strlen("xxx"));
12+
} catch (Error $e) {
13+
echo $e->getMessage(), "\n";
14+
}
15+
try {
16+
var_dump(defined("PHP_VERSION"));
17+
} catch (Error $e) {
18+
echo $e->getMessage(), "\n";
19+
}
20+
try {
21+
var_dump(constant("PHP_VERSION"));
22+
} catch (Error $e) {
23+
echo $e->getMessage(), "\n";
24+
}
25+
try {
26+
var_dump(call_user_func("strlen"));
27+
} catch (Error $e) {
28+
echo $e->getMessage(), "\n";
29+
}
30+
try {
31+
var_dump(is_string("xxx"));
32+
} catch (Error $e) {
33+
echo $e->getMessage(), "\n";
34+
}
35+
try {
36+
var_dump(is_string());
37+
} catch (Error $e) {
38+
echo $e->getMessage(), "\n";
39+
}
1640

1741
?>
18-
--EXPECTF--
42+
--EXPECT--
1943
bool(false)
20-
bool(true)
21-
22-
Warning: strlen() has been disabled for security reasons in %sbug69315.php on line %d
23-
NULL
24-
25-
Warning: defined() has been disabled for security reasons in %sbug69315.php on line %d
26-
NULL
27-
28-
Warning: constant() has been disabled for security reasons in %sbug69315.php on line %d
29-
NULL
30-
31-
Warning: call_user_func() has been disabled for security reasons in %sbug69315.php on line %d
32-
NULL
33-
34-
Warning: is_string() has been disabled for security reasons in %sbug69315.php on line %d
35-
NULL
36-
37-
Warning: is_string() has been disabled for security reasons in %s on line %d
38-
NULL
44+
bool(false)
45+
Call to undefined function strlen()
46+
Call to undefined function defined()
47+
Call to undefined function constant()
48+
Call to undefined function call_user_func()
49+
Call to undefined function is_string()
50+
Call to undefined function is_string()

Zend/tests/bug79382.phpt

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
--TEST--
2+
Bug #79382: Cannot redeclare disabled function
3+
--INI--
4+
disable_functions=strlen
5+
--FILE--
6+
<?php
7+
8+
function strlen(string $x): int {
9+
$len = 0;
10+
while (isset($x[$len])) $len++;
11+
return $len;
12+
}
13+
14+
var_dump(strlen("foobar"));
15+
16+
?>
17+
--EXPECT--
18+
int(6)

Zend/tests/errmsg_020.phpt

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,12 @@ disable_functions=phpinfo
55
--FILE--
66
<?php
77

8-
phpinfo();
8+
try {
9+
phpinfo();
10+
} catch (Error $e) {
11+
echo $e->getMessage(), "\n";
12+
}
913

10-
echo "Done\n";
1114
?>
12-
--EXPECTF--
13-
Warning: phpinfo() has been disabled for security reasons in %s on line %d
14-
Done
15+
--EXPECT--
16+
Call to undefined function phpinfo()

Zend/zend_API.c

Lines changed: 1 addition & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2686,27 +2686,9 @@ ZEND_API int zend_set_hash_symbol(zval *symbol, const char *name, int name_lengt
26862686

26872687
/* Disabled functions support */
26882688

2689-
/* {{{ proto void display_disabled_function(void)
2690-
Dummy function which displays an error when a disabled function is called. */
2691-
ZEND_API ZEND_COLD ZEND_FUNCTION(display_disabled_function)
2692-
{
2693-
zend_error(E_WARNING, "%s() has been disabled for security reasons", get_active_function_name());
2694-
}
2695-
/* }}} */
2696-
26972689
ZEND_API int zend_disable_function(char *function_name, size_t function_name_length) /* {{{ */
26982690
{
2699-
zend_internal_function *func;
2700-
if ((func = zend_hash_str_find_ptr(CG(function_table), function_name, function_name_length))) {
2701-
zend_free_internal_arg_info(func);
2702-
func->fn_flags &= ~(ZEND_ACC_VARIADIC | ZEND_ACC_HAS_TYPE_HINTS | ZEND_ACC_HAS_RETURN_TYPE);
2703-
func->num_args = 0;
2704-
func->required_num_args = 0;
2705-
func->arg_info = NULL;
2706-
func->handler = ZEND_FN(display_disabled_function);
2707-
return SUCCESS;
2708-
}
2709-
return FAILURE;
2691+
return zend_hash_str_del(CG(function_table), function_name, function_name_length);
27102692
}
27112693
/* }}} */
27122694

Zend/zend_API.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -593,8 +593,6 @@ ZEND_API zend_bool zend_is_iterable(zval *iterable);
593593

594594
ZEND_API zend_bool zend_is_countable(zval *countable);
595595

596-
ZEND_API ZEND_FUNCTION(display_disabled_function);
597-
598596
ZEND_API int zend_get_default_from_internal_arg_info(
599597
zval *default_value_zval, zend_internal_arg_info *arg_info);
600598

Zend/zend_builtin_functions.c

Lines changed: 7 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1127,7 +1127,7 @@ ZEND_FUNCTION(trait_exists)
11271127
ZEND_FUNCTION(function_exists)
11281128
{
11291129
zend_string *name;
1130-
zend_function *func;
1130+
zend_bool exists;
11311131
zend_string *lcname;
11321132

11331133
ZEND_PARSE_PARAMETERS_START(1, 1)
@@ -1142,15 +1142,10 @@ ZEND_FUNCTION(function_exists)
11421142
lcname = zend_string_tolower(name);
11431143
}
11441144

1145-
func = zend_hash_find_ptr(EG(function_table), lcname);
1145+
exists = zend_hash_exists(EG(function_table), lcname);
11461146
zend_string_release_ex(lcname, 0);
11471147

1148-
/*
1149-
* A bit of a hack, but not a bad one: we see if the handler of the function
1150-
* is actually one that displays "function is disabled" message.
1151-
*/
1152-
RETURN_BOOL(func && (func->type != ZEND_INTERNAL_FUNCTION ||
1153-
func->internal_function.handler != zif_display_disabled_function));
1148+
RETURN_BOOL(exists);
11541149
}
11551150
/* }}} */
11561151

@@ -1420,30 +1415,22 @@ ZEND_FUNCTION(get_defined_functions)
14201415
zval internal, user;
14211416
zend_string *key;
14221417
zend_function *func;
1423-
zend_bool exclude_disabled = 0;
1424-
char *disable_functions = NULL;
1418+
zend_bool exclude_disabled = 1;
14251419

14261420
if (zend_parse_parameters(ZEND_NUM_ARGS(), "|b", &exclude_disabled) == FAILURE) {
14271421
RETURN_THROWS();
14281422
}
14291423

1424+
/* exclude_disabled = 0 is ignored. */
1425+
14301426
array_init(&internal);
14311427
array_init(&user);
14321428
array_init(return_value);
14331429

1434-
if (exclude_disabled) {
1435-
disable_functions = INI_STR("disable_functions");
1436-
}
14371430
ZEND_HASH_FOREACH_STR_KEY_PTR(EG(function_table), key, func) {
14381431
if (key && ZSTR_VAL(key)[0] != 0) {
14391432
if (func->type == ZEND_INTERNAL_FUNCTION) {
1440-
if (disable_functions != NULL) {
1441-
if (strstr(disable_functions, func->common.function_name->val) == NULL) {
1442-
add_next_index_str(&internal, zend_string_copy(key));
1443-
}
1444-
} else {
1445-
add_next_index_str(&internal, zend_string_copy(key));
1446-
}
1433+
add_next_index_str(&internal, zend_string_copy(key));
14471434
} else if (func->type == ZEND_USER_FUNCTION) {
14481435
add_next_index_str(&user, zend_string_copy(key));
14491436
}

Zend/zend_builtin_functions.stub.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ function get_declared_traits(): array {}
8585

8686
function get_declared_interfaces(): array {}
8787

88-
function get_defined_functions(bool $exclude_disabled = false): array {}
88+
function get_defined_functions(bool $exclude_disabled = true): array {}
8989

9090
function get_defined_vars(): array {}
9191

Zend/zend_builtin_functions_arginfo.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ ZEND_END_ARG_INFO()
146146
#define arginfo_get_declared_interfaces arginfo_func_get_args
147147

148148
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_get_defined_functions, 0, 0, IS_ARRAY, 0)
149-
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, exclude_disabled, _IS_BOOL, 0, "false")
149+
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, exclude_disabled, _IS_BOOL, 0, "true")
150150
ZEND_END_ARG_INFO()
151151

152152
#define arginfo_get_defined_vars arginfo_func_get_args

Zend/zend_compile.c

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3934,10 +3934,6 @@ int zend_compile_func_array_slice(znode *result, zend_ast_list *args) /* {{{ */
39343934

39353935
int zend_try_compile_special_func(znode *result, zend_string *lcname, zend_ast_list *args, zend_function *fbc, uint32_t type) /* {{{ */
39363936
{
3937-
if (fbc->internal_function.handler == ZEND_FN(display_disabled_function)) {
3938-
return FAILURE;
3939-
}
3940-
39413937
if (CG(compiler_options) & ZEND_COMPILE_NO_BUILTINS) {
39423938
return FAILURE;
39433939
}

ext/opcache/Optimizer/pass1.c

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -382,12 +382,10 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx)
382382
Z_TYPE(ZEND_OP1_LITERAL(send1_opline)) == IS_STRING) {
383383
if ((Z_STRLEN(ZEND_OP2_LITERAL(init_opline)) == sizeof("function_exists")-1 &&
384384
!memcmp(Z_STRVAL(ZEND_OP2_LITERAL(init_opline)),
385-
"function_exists", sizeof("function_exists")-1) &&
386-
!zend_optimizer_is_disabled_func("function_exists", sizeof("function_exists") - 1)) ||
385+
"function_exists", sizeof("function_exists")-1)) ||
387386
(Z_STRLEN(ZEND_OP2_LITERAL(init_opline)) == sizeof("is_callable")-1 &&
388387
!memcmp(Z_STRVAL(ZEND_OP2_LITERAL(init_opline)),
389-
"is_callable", sizeof("is_callable")) &&
390-
!zend_optimizer_is_disabled_func("is_callable", sizeof("is_callable") - 1))) {
388+
"is_callable", sizeof("is_callable")))) {
391389
zend_internal_function *func;
392390
zend_string *lc_name = zend_string_tolower(
393391
Z_STR(ZEND_OP1_LITERAL(send1_opline)));
@@ -400,12 +398,7 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx)
400398
#endif
401399
) {
402400
zval t;
403-
if (Z_STRLEN(ZEND_OP2_LITERAL(init_opline)) == sizeof("is_callable") - 1 ||
404-
func->handler != ZEND_FN(display_disabled_function)) {
405-
ZVAL_TRUE(&t);
406-
} else {
407-
ZVAL_FALSE(&t);
408-
}
401+
ZVAL_TRUE(&t);
409402
literal_dtor(&ZEND_OP2_LITERAL(init_opline));
410403
MAKE_NOP(init_opline);
411404
literal_dtor(&ZEND_OP1_LITERAL(send1_opline));
@@ -423,8 +416,7 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx)
423416
break;
424417
} else if (Z_STRLEN(ZEND_OP2_LITERAL(init_opline)) == sizeof("extension_loaded")-1 &&
425418
!memcmp(Z_STRVAL(ZEND_OP2_LITERAL(init_opline)),
426-
"extension_loaded", sizeof("extension_loaded")-1) &&
427-
!zend_optimizer_is_disabled_func("extension_loaded", sizeof("extension_loaded") - 1)) {
419+
"extension_loaded", sizeof("extension_loaded")-1)) {
428420
zval t;
429421
zend_string *lc_name = zend_string_tolower(
430422
Z_STR(ZEND_OP1_LITERAL(send1_opline)));
@@ -465,8 +457,7 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx)
465457
break;
466458
} else if (Z_STRLEN(ZEND_OP2_LITERAL(init_opline)) == sizeof("constant")-1 &&
467459
!memcmp(Z_STRVAL(ZEND_OP2_LITERAL(init_opline)),
468-
"constant", sizeof("constant")-1) &&
469-
!zend_optimizer_is_disabled_func("constant", sizeof("constant") - 1)) {
460+
"constant", sizeof("constant")-1)) {
470461
zval t;
471462

472463
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)
488479
} else if (Z_STRLEN(ZEND_OP2_LITERAL(init_opline)) == sizeof("dirname")-1 &&
489480
!memcmp(Z_STRVAL(ZEND_OP2_LITERAL(init_opline)),
490481
"dirname", sizeof("dirname") - 1) &&
491-
!zend_optimizer_is_disabled_func("dirname", sizeof("dirname") - 1) &&
492482
IS_ABSOLUTE_PATH(Z_STRVAL(ZEND_OP1_LITERAL(send1_opline)), Z_STRLEN(ZEND_OP1_LITERAL(send1_opline)))) {
493483
zend_string *dirname = zend_string_init(Z_STRVAL(ZEND_OP1_LITERAL(send1_opline)), Z_STRLEN(ZEND_OP1_LITERAL(send1_opline)), 0);
494484
ZSTR_LEN(dirname) = zend_dirname(ZSTR_VAL(dirname), ZSTR_LEN(dirname));

ext/opcache/Optimizer/sccp.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1019,8 +1019,7 @@ static inline int ct_eval_func_call(
10191019
}
10201020

10211021
func = zend_hash_find_ptr(CG(function_table), name);
1022-
if (!func || func->type != ZEND_INTERNAL_FUNCTION
1023-
|| func->internal_function.handler == ZEND_FN(display_disabled_function)) {
1022+
if (!func || func->type != ZEND_INTERNAL_FUNCTION) {
10241023
return FAILURE;
10251024
}
10261025

ext/opcache/Optimizer/zend_func_info.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -902,9 +902,7 @@ uint32_t zend_get_func_info(
902902
if (!call_info->callee_func->common.scope
903903
&& (zv = zend_hash_find_ex(&func_info, lcname, 1))) {
904904
func_info_t *info = Z_PTR_P(zv);
905-
if (UNEXPECTED(zend_optimizer_is_disabled_func(info->name, info->name_len))) {
906-
ret = MAY_BE_NULL;
907-
} else if (info->info_func) {
905+
if (info->info_func) {
908906
ret = info->info_func(call_info, ssa);
909907
} else {
910908
ret = info->info;

ext/opcache/Optimizer/zend_optimizer.c

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -157,13 +157,6 @@ static inline int zend_optimizer_add_literal_string(zend_op_array *op_array, zen
157157
return zend_optimizer_add_literal(op_array, &zv);
158158
}
159159

160-
int zend_optimizer_is_disabled_func(const char *name, size_t len) {
161-
zend_function *fbc = (zend_function *)zend_hash_str_find_ptr(EG(function_table), name, len);
162-
163-
return (fbc && fbc->type == ZEND_INTERNAL_FUNCTION &&
164-
fbc->internal_function.handler == ZEND_FN(display_disabled_function));
165-
}
166-
167160
static inline void drop_leading_backslash(zval *val) {
168161
if (Z_STRVAL_P(val)[0] == '\\') {
169162
zend_string *str = zend_string_init(Z_STRVAL_P(val) + 1, Z_STRLEN_P(val) - 1, 0);

ext/opcache/Optimizer/zend_optimizer_internal.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,6 @@ void zend_optimize_temporary_variables(zend_op_array *op_array, zend_optimizer_c
108108
void zend_optimizer_nop_removal(zend_op_array *op_array, zend_optimizer_ctx *ctx);
109109
void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx *ctx);
110110
void zend_optimizer_compact_vars(zend_op_array *op_array);
111-
int zend_optimizer_is_disabled_func(const char *name, size_t len);
112111
zend_function *zend_optimizer_get_called_func(
113112
zend_script *script, zend_op_array *op_array, zend_op *opline, zend_bool *is_prototype);
114113
uint32_t zend_optimizer_classify_function(zend_string *name, uint32_t num_args);

ext/opcache/tests/bug68104.phpt

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,12 @@ disable_functions=dl
1111
--FILE--
1212
<?php
1313
var_dump(is_callable("dl"));
14-
dl("a.so");
14+
try {
15+
dl("a.so");
16+
} catch (Error $e) {
17+
echo $e->getMessage(), "\n";
18+
}
1519
?>
16-
--EXPECTF--
17-
bool(true)
18-
19-
Warning: dl() has been disabled for security reasons in %sbug68104.php on line %d
20+
--EXPECT--
21+
bool(false)
22+
Call to undefined function dl()

ext/opcache/tests/bug76796.phpt

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,12 @@ disable_functions=strpos
1010
--FILE--
1111
<?php
1212

13-
var_dump(strpos('foo', 'bar'));
13+
try {
14+
var_dump(strpos('foo', 'bar'));
15+
} catch (Error $e) {
16+
echo $e->getMessage(), "\n";
17+
}
1418

1519
?>
16-
--EXPECTF--
17-
Warning: strpos() has been disabled for security reasons in %s on line %d
18-
NULL
20+
--EXPECT--
21+
Call to undefined function strpos()

ext/reflection/php_reflection.c

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1549,16 +1549,12 @@ ZEND_METHOD(ReflectionFunctionAbstract, isUserDefined)
15491549
Returns whether this function has been disabled or not */
15501550
ZEND_METHOD(ReflectionFunction, isDisabled)
15511551
{
1552-
reflection_object *intern;
1553-
zend_function *fptr;
1554-
1555-
GET_REFLECTION_OBJECT_PTR(fptr);
1556-
15571552
if (zend_parse_parameters_none() == FAILURE) {
15581553
RETURN_THROWS();
15591554
}
15601555

1561-
RETURN_BOOL(fptr->type == ZEND_INTERNAL_FUNCTION && fptr->internal_function.handler == zif_display_disabled_function);
1556+
/* A disabled function cannot be queried using Reflection. */
1557+
RETURN_FALSE;
15621558
}
15631559
/* }}} */
15641560

0 commit comments

Comments
 (0)