Skip to content

Commit 2c15c9c

Browse files
committed
Rehash function table after disabling functions
To perform fast shutdown without full table cleanup we need all internal functions to be in one continuous chunk. This was violated when functions were deleted via disable_functions. This drops the zend_disable_function() API in favor of zend_disable_functions(), which disables the given list of functions and performs the necessary rehash afterwards. Also drop PG(disabled_functions), which is no longer used.
1 parent 138f141 commit 2c15c9c

File tree

5 files changed

+39
-48
lines changed

5 files changed

+39
-48
lines changed

Zend/zend_API.c

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2790,9 +2790,43 @@ ZEND_API zend_result zend_set_hash_symbol(zval *symbol, const char *name, size_t
27902790

27912791
/* Disabled functions support */
27922792

2793-
ZEND_API zend_result zend_disable_function(const char *function_name, size_t function_name_length) /* {{{ */
2793+
static void zend_disable_function(const char *function_name, size_t function_name_length)
27942794
{
2795-
return zend_hash_str_del(CG(function_table), function_name, function_name_length);
2795+
zend_hash_str_del(CG(function_table), function_name, function_name_length);
2796+
}
2797+
2798+
ZEND_API void zend_disable_functions(const char *function_list) /* {{{ */
2799+
{
2800+
if (!function_list || !*function_list) {
2801+
return;
2802+
}
2803+
2804+
const char *s = NULL, *e = function_list;
2805+
while (*e) {
2806+
switch (*e) {
2807+
case ' ':
2808+
case ',':
2809+
if (s) {
2810+
zend_disable_function(s, e - s);
2811+
s = NULL;
2812+
}
2813+
break;
2814+
default:
2815+
if (!s) {
2816+
s = e;
2817+
}
2818+
break;
2819+
}
2820+
e++;
2821+
}
2822+
if (s) {
2823+
zend_disable_function(s, e - s);
2824+
}
2825+
2826+
/* Rehash the function table after deleting functions. This ensures that all internal
2827+
* functions are contiguous, which means we don't need to perform full table cleanup
2828+
* on shutdown. */
2829+
zend_hash_rehash(CG(function_table));
27962830
}
27972831
/* }}} */
27982832

Zend/zend_API.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -341,7 +341,7 @@ ZEND_API zend_result zend_register_class_alias_ex(const char *name, size_t name_
341341
#define zend_register_ns_class_alias(ns, name, ce) \
342342
zend_register_class_alias_ex(ZEND_NS_NAME(ns, name), sizeof(ZEND_NS_NAME(ns, name))-1, ce, 1)
343343

344-
ZEND_API zend_result zend_disable_function(const char *function_name, size_t function_name_length);
344+
ZEND_API void zend_disable_functions(const char *function_list);
345345
ZEND_API zend_result zend_disable_class(const char *class_name, size_t class_name_length);
346346

347347
ZEND_API ZEND_COLD void zend_wrong_param_count(void);

main/main.c

Lines changed: 1 addition & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -299,43 +299,6 @@ static PHP_INI_MH(OnSetLogFilter)
299299
}
300300
/* }}} */
301301

302-
/* {{{ php_disable_functions */
303-
static void php_disable_functions(void)
304-
{
305-
char *s = NULL, *e;
306-
307-
if (!*(INI_STR("disable_functions"))) {
308-
return;
309-
}
310-
311-
e = PG(disable_functions) = strdup(INI_STR("disable_functions"));
312-
if (e == NULL) {
313-
return;
314-
}
315-
while (*e) {
316-
switch (*e) {
317-
case ' ':
318-
case ',':
319-
if (s) {
320-
*e = '\0';
321-
zend_disable_function(s, e-s);
322-
s = NULL;
323-
}
324-
break;
325-
default:
326-
if (!s) {
327-
s = e;
328-
}
329-
break;
330-
}
331-
e++;
332-
}
333-
if (s) {
334-
zend_disable_function(s, e-s);
335-
}
336-
}
337-
/* }}} */
338-
339302
/* {{{ php_disable_classes */
340303
static void php_disable_classes(void)
341304
{
@@ -1924,9 +1887,6 @@ static void core_globals_dtor(php_core_globals *core_globals)
19241887
ZEND_ASSERT(!core_globals->last_error_message);
19251888
ZEND_ASSERT(!core_globals->last_error_file);
19261889

1927-
if (core_globals->disable_functions) {
1928-
free(core_globals->disable_functions);
1929-
}
19301890
if (core_globals->disable_classes) {
19311891
free(core_globals->disable_classes);
19321892
}
@@ -2274,7 +2234,7 @@ int php_module_startup(sapi_module_struct *sf, zend_module_entry *additional_mod
22742234
}
22752235

22762236
/* disable certain classes and functions as requested by php.ini */
2277-
php_disable_functions();
2237+
zend_disable_functions(INI_STR("disable_functions"));
22782238
php_disable_classes();
22792239

22802240
/* make core report what it should */

main/php_globals.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,6 @@ struct _php_core_globals {
139139

140140
char *php_sys_temp_dir;
141141

142-
char *disable_functions;
143142
char *disable_classes;
144143
zend_bool allow_url_include;
145144
#ifdef PHP_WIN32

sapi/fpm/fpm/fpm_php.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -96,9 +96,7 @@ int fpm_php_apply_defines_ex(struct key_value_s *kv, int mode) /* {{{ */
9696
}
9797

9898
if (!strcmp(name, "disable_functions") && *value) {
99-
char *v = strdup(value);
100-
PG(disable_functions) = v;
101-
fpm_php_disable(v, zend_disable_function);
99+
zend_disable_functions(value);
102100
return 1;
103101
}
104102

0 commit comments

Comments
 (0)