]> granicus.if.org Git - php/commitdiff
fix the empty_strings SAPI shutdown leak in TS build
authorAnatol Belski <ab@php.net>
Mon, 6 Oct 2014 13:44:43 +0000 (15:44 +0200)
committerAnatol Belski <ab@php.net>
Mon, 6 Oct 2014 13:48:55 +0000 (15:48 +0200)
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

Zend/zend.c
Zend/zend_string.c
Zend/zend_string.h

index 2762b0922ef86ff63c53769a69bd96a6afa010e2..eb91026a2434026cdc9b8bf129097cd68ad5f0f5 100644 (file)
@@ -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
 }
 /* }}} */
index a2fe091695fae4ec789853def7c62ff01c8d9609..1833bbd241b5d6b9088978f8e9b6bc40c34a1454 100644 (file)
@@ -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
 }
 
index d30e14b5b3999a94bf6f7e6b0c454e474ee21309..1da3b511c0b0f98fc7cd01137aec58d76e4b5d2b 100644 (file)
@@ -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 */
 
 /*