diff options
| author | Anatol Belski <ab@php.net> | 2014-10-06 15:44:43 +0200 | 
|---|---|---|
| committer | Anatol Belski <ab@php.net> | 2014-10-06 15:48:55 +0200 | 
| commit | 741bf0ee9626c9342de1175244d9e9e4ad9c69f4 (patch) | |
| tree | d4042b862a97fea3878a3fc52a50de18355e6c8c | |
| parent | cc7c14cb76013c8a66b74cfb423135d41a709403 (diff) | |
| download | php-git-741bf0ee9626c9342de1175244d9e9e4ad9c69f4.tar.gz | |
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
| -rw-r--r-- | Zend/zend.c | 10 | ||||
| -rw-r--r-- | Zend/zend_string.c | 13 | ||||
| -rw-r--r-- | Zend/zend_string.h | 24 | 
3 files changed, 27 insertions, 20 deletions
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 */  /*  | 
