From: Anatol Belski Date: Mon, 6 Oct 2014 13:44:43 +0000 (+0200) Subject: fix the empty_strings SAPI shutdown leak in TS build X-Git-Tag: POST_NATIVE_TLS_MERGE^2~82^2~1 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=741bf0ee9626c9342de1175244d9e9e4ad9c69f4;p=php fix the empty_strings SAPI shutdown leak in TS build still the NTS variant is somewhat different as it needs zend_new_interned_string_int because the normal callbacks might be not initialized, but at least no leaks anymore and some more structure --- diff --git a/Zend/zend.c b/Zend/zend.c index 2762b0922e..eb91026a24 100644 --- a/Zend/zend.c +++ b/Zend/zend.c @@ -444,10 +444,7 @@ static void compiler_globals_ctor(zend_compiler_globals *compiler_globals TSRMLS compiler_globals->script_encoding_list = NULL; #ifdef ZTS - compiler_globals->empty_string = zend_string_alloc(sizeof("")-1, 1); - compiler_globals->empty_string->val[0] = '\000'; - zend_string_hash_val(compiler_globals->empty_string); - compiler_globals->empty_string->gc.u.v.flags |= IS_STR_INTERNED; + zend_interned_empty_string_init(&compiler_globals->empty_string TSRMLS_CC); memset(compiler_globals->one_char_string, 0, sizeof(compiler_globals->one_char_string)); #endif @@ -477,10 +474,7 @@ static void compiler_globals_dtor(zend_compiler_globals *compiler_globals TSRMLS compiler_globals->last_static_member = 0; #ifdef ZTS - if (NULL != compiler_globals->empty_string) { - free(compiler_globals->empty_string); - compiler_globals->empty_string = NULL; - } + zend_interned_empty_string_free(&compiler_globals->empty_string TSRMLS_CC); #endif } /* }}} */ diff --git a/Zend/zend_string.c b/Zend/zend_string.c index a2fe091695..1833bbd241 100644 --- a/Zend/zend_string.c +++ b/Zend/zend_string.c @@ -45,9 +45,9 @@ static void _str_dtor(zval *zv) void zend_interned_strings_init(TSRMLS_D) { +#ifndef ZTS zend_string *str; -#ifndef ZTS zend_hash_init(&CG(interned_strings), 1024, NULL, _str_dtor, 1); CG(interned_strings).nTableMask = CG(interned_strings).nTableSize - 1; @@ -59,12 +59,6 @@ void zend_interned_strings_init(TSRMLS_D) str = zend_string_alloc(sizeof("")-1, 1); str->val[0] = '\000'; CG(empty_string) = zend_new_interned_string_int(str TSRMLS_CC); -#else - str = zend_string_alloc(sizeof("")-1, 1); - str->val[0] = '\000'; - zend_string_hash_val(str); - str->gc.u.v.flags |= IS_STR_INTERNED; - CG(empty_string) = str; #endif /* one char strings (the actual interned strings are going to be created by ext/opcache) */ @@ -79,11 +73,6 @@ void zend_interned_strings_dtor(TSRMLS_D) { #ifndef ZTS zend_hash_destroy(&CG(interned_strings)); -#else - if (NULL != CG(empty_string)) { - free(CG(empty_string)); - CG(empty_string) = NULL; - } #endif } diff --git a/Zend/zend_string.h b/Zend/zend_string.h index d30e14b5b3..1da3b511c0 100644 --- a/Zend/zend_string.h +++ b/Zend/zend_string.h @@ -282,6 +282,30 @@ EMPTY_SWITCH_DEFAULT_CASE() return hash; } +static zend_always_inline void zend_interned_empty_string_init(zend_string **s TSRMLS_DC) +{ + zend_string *str; + + str = zend_string_alloc(sizeof("")-1, 1); + str->val[0] = '\000'; + +#ifndef ZTS + *s = zend_new_interned_string(str TSRMLS_CC); +#else + zend_string_hash_val(str); + str->gc.u.v.flags |= IS_STR_INTERNED; + *s = str; +#endif +} + +static zend_always_inline void zend_interned_empty_string_free(zend_string **s TSRMLS_DC) +{ + if (NULL != *s) { + free(*s); + *s = NULL; + } +} + #endif /* ZEND_STRING_H */ /*