From 3b2e8583043eeee77ef9526476ec0959814daa6b Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Thu, 2 Nov 2017 14:09:06 +0300 Subject: [PATCH] Overlad functions once in MINIT (instead of on each requestr in RINIT) --- ext/mbstring/mbstring.c | 106 ++++++++++++++++++++++------------------ 1 file changed, 58 insertions(+), 48 deletions(-) diff --git a/ext/mbstring/mbstring.c b/ext/mbstring/mbstring.c index 40938d88e8..12cdac9cda 100644 --- a/ext/mbstring/mbstring.c +++ b/ext/mbstring/mbstring.c @@ -1603,6 +1603,45 @@ ZEND_TSRMLS_CACHE_UPDATE(); php_mb_rfc1867_getword_conf, php_mb_rfc1867_basename); + /* override original function (deprecated). */ + if (MBSTRG(func_overload)){ + zend_function *func, *orig; + const struct mb_overload_def *p; + zend_string *str; + void *ret; + + p = &(mb_ovld[0]); + while (p->type > 0) { + if ((MBSTRG(func_overload) & p->type) == p->type && + !zend_hash_str_exists(CG(function_table), p->save_func, strlen(p->save_func)) + ) { + func = zend_hash_str_find_ptr(CG(function_table), p->ovld_func, strlen(p->ovld_func)); + + if ((orig = zend_hash_str_find_ptr(CG(function_table), p->orig_func, strlen(p->orig_func))) == NULL) { + php_error_docref("ref.mbstring", E_WARNING, "mbstring couldn't find function %s.", p->orig_func); + return FAILURE; + } else { + ZEND_ASSERT(orig->type == ZEND_INTERNAL_FUNCTION); + str = zend_string_init_interned(p->save_func, strlen(p->save_func), 1); + zend_hash_add_mem(CG(function_table), str, orig, sizeof(zend_internal_function)); + zend_string_release(str); + function_add_ref(orig); + + str = zend_string_init_interned(p->orig_func, strlen(p->orig_func), 1); + ret = zend_hash_update_mem(CG(function_table), str, func, sizeof(zend_internal_function)); + zend_string_release(str); + if (ret == NULL) { + php_error_docref("ref.mbstring", E_WARNING, "mbstring couldn't replace function %s.", p->orig_func); + return FAILURE; + } + + function_add_ref(func); + } + } + p++; + } + } + return SUCCESS; } /* }}} */ @@ -1610,6 +1649,24 @@ ZEND_TSRMLS_CACHE_UPDATE(); /* {{{ PHP_MSHUTDOWN_FUNCTION(mbstring) */ PHP_MSHUTDOWN_FUNCTION(mbstring) { + /* clear overloaded function. */ + if (MBSTRG(func_overload)){ + const struct mb_overload_def *p; + zend_function *orig; + + p = &(mb_ovld[0]); + while (p->type > 0) { + if ((MBSTRG(func_overload) & p->type) == p->type && + (orig = zend_hash_str_find_ptr(CG(function_table), p->save_func, strlen(p->save_func)))) { + + zend_hash_str_update_mem(CG(function_table), p->orig_func, strlen(p->orig_func), orig, sizeof(zend_internal_function)); + function_add_ref(orig); + zend_hash_str_del(CG(function_table), p->save_func, strlen(p->save_func)); + } + p++; + } + } + UNREGISTER_INI_ENTRIES(); zend_multibyte_restore_functions(); @@ -1625,9 +1682,6 @@ PHP_MSHUTDOWN_FUNCTION(mbstring) /* {{{ PHP_RINIT_FUNCTION(mbstring) */ PHP_RINIT_FUNCTION(mbstring) { - zend_function *func, *orig; - const struct mb_overload_def *p; - MBSTRG(current_internal_encoding) = MBSTRG(internal_encoding); MBSTRG(current_http_output_encoding) = MBSTRG(http_output_encoding); MBSTRG(current_filter_illegal_mode) = MBSTRG(filter_illegal_mode); @@ -1637,36 +1691,11 @@ PHP_RINIT_FUNCTION(mbstring) php_mb_populate_current_detect_order_list(); - /* override original function. */ + /* override original function. */ if (MBSTRG(func_overload)){ zend_error(E_DEPRECATED, "The mbstring.func_overload directive is deprecated"); - p = &(mb_ovld[0]); CG(compiler_options) |= ZEND_COMPILE_NO_BUILTIN_STRLEN; - while (p->type > 0) { - if ((MBSTRG(func_overload) & p->type) == p->type && - !zend_hash_str_exists(EG(function_table), p->save_func, strlen(p->save_func)) - ) { - func = zend_hash_str_find_ptr(EG(function_table), p->ovld_func, strlen(p->ovld_func)); - - if ((orig = zend_hash_str_find_ptr(EG(function_table), p->orig_func, strlen(p->orig_func))) == NULL) { - php_error_docref("ref.mbstring", E_WARNING, "mbstring couldn't find function %s.", p->orig_func); - return FAILURE; - } else { - ZEND_ASSERT(orig->type == ZEND_INTERNAL_FUNCTION); - zend_hash_str_add_mem(EG(function_table), p->save_func, strlen(p->save_func), orig, sizeof(zend_internal_function)); - function_add_ref(orig); - - if (zend_hash_str_update_mem(EG(function_table), p->orig_func, strlen(p->orig_func), func, sizeof(zend_internal_function)) == NULL) { - php_error_docref("ref.mbstring", E_WARNING, "mbstring couldn't replace function %s.", p->orig_func); - return FAILURE; - } - - function_add_ref(func); - } - } - p++; - } } #if HAVE_MBREGEX PHP_RINIT(mb_regex) (INIT_FUNC_ARGS_PASSTHRU); @@ -1680,9 +1709,6 @@ PHP_RINIT_FUNCTION(mbstring) /* {{{ PHP_RSHUTDOWN_FUNCTION(mbstring) */ PHP_RSHUTDOWN_FUNCTION(mbstring) { - const struct mb_overload_def *p; - zend_function *orig; - if (MBSTRG(current_detect_order_list) != NULL) { efree(MBSTRG(current_detect_order_list)); MBSTRG(current_detect_order_list) = NULL; @@ -1706,22 +1732,6 @@ PHP_RSHUTDOWN_FUNCTION(mbstring) MBSTRG(last_used_encoding_name) = NULL; } - /* clear overloaded function. */ - if (MBSTRG(func_overload)){ - p = &(mb_ovld[0]); - while (p->type > 0) { - if ((MBSTRG(func_overload) & p->type) == p->type && - (orig = zend_hash_str_find_ptr(EG(function_table), p->save_func, strlen(p->save_func)))) { - - zend_hash_str_update_mem(EG(function_table), p->orig_func, strlen(p->orig_func), orig, sizeof(zend_internal_function)); - function_add_ref(orig); - zend_hash_str_del(EG(function_table), p->save_func, strlen(p->save_func)); - } - p++; - } - CG(compiler_options) &= ~ZEND_COMPILE_NO_BUILTIN_STRLEN; - } - #if HAVE_MBREGEX PHP_RSHUTDOWN(mb_regex) (INIT_FUNC_ARGS_PASSTHRU); #endif -- 2.40.0