summaryrefslogtreecommitdiff
path: root/Zend
diff options
context:
space:
mode:
authorNikita Popov <nikita.ppv@gmail.com>2020-08-28 16:43:22 +0200
committerNikita Popov <nikita.ppv@gmail.com>2020-08-28 16:50:07 +0200
commit2c15c9ce80b0c8779a3d5cc5ad1c3452e620d084 (patch)
tree0fbbf25329c9ac7ce978efd0cfebb26de14403e2 /Zend
parent138f14160569a52ffedfb789d0a8162741ec87b3 (diff)
downloadphp-git-2c15c9ce80b0c8779a3d5cc5ad1c3452e620d084.tar.gz
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.
Diffstat (limited to 'Zend')
-rw-r--r--Zend/zend_API.c38
-rw-r--r--Zend/zend_API.h2
2 files changed, 37 insertions, 3 deletions
diff --git a/Zend/zend_API.c b/Zend/zend_API.c
index ae33bf3022..139e11e937 100644
--- a/Zend/zend_API.c
+++ b/Zend/zend_API.c
@@ -2790,9 +2790,43 @@ ZEND_API zend_result zend_set_hash_symbol(zval *symbol, const char *name, size_t
/* Disabled functions support */
-ZEND_API zend_result zend_disable_function(const char *function_name, size_t function_name_length) /* {{{ */
+static void zend_disable_function(const char *function_name, size_t function_name_length)
{
- return zend_hash_str_del(CG(function_table), function_name, function_name_length);
+ zend_hash_str_del(CG(function_table), function_name, function_name_length);
+}
+
+ZEND_API void zend_disable_functions(const char *function_list) /* {{{ */
+{
+ if (!function_list || !*function_list) {
+ return;
+ }
+
+ const char *s = NULL, *e = function_list;
+ while (*e) {
+ switch (*e) {
+ case ' ':
+ case ',':
+ if (s) {
+ zend_disable_function(s, e - s);
+ s = NULL;
+ }
+ break;
+ default:
+ if (!s) {
+ s = e;
+ }
+ break;
+ }
+ e++;
+ }
+ if (s) {
+ zend_disable_function(s, e - s);
+ }
+
+ /* Rehash the function table after deleting functions. This ensures that all internal
+ * functions are contiguous, which means we don't need to perform full table cleanup
+ * on shutdown. */
+ zend_hash_rehash(CG(function_table));
}
/* }}} */
diff --git a/Zend/zend_API.h b/Zend/zend_API.h
index 6f028ae65e..d46fe6968a 100644
--- a/Zend/zend_API.h
+++ b/Zend/zend_API.h
@@ -341,7 +341,7 @@ ZEND_API zend_result zend_register_class_alias_ex(const char *name, size_t name_
#define zend_register_ns_class_alias(ns, name, ce) \
zend_register_class_alias_ex(ZEND_NS_NAME(ns, name), sizeof(ZEND_NS_NAME(ns, name))-1, ce, 1)
-ZEND_API zend_result zend_disable_function(const char *function_name, size_t function_name_length);
+ZEND_API void zend_disable_functions(const char *function_list);
ZEND_API zend_result zend_disable_class(const char *class_name, size_t class_name_length);
ZEND_API ZEND_COLD void zend_wrong_param_count(void);