]> granicus.if.org Git - php/commitdiff
BugFix#28868 (Part Two): This fixes thread unsafety in the userspace
authorSara Golemon <pollita@php.net>
Mon, 21 Jun 2004 21:08:05 +0000 (21:08 +0000)
committerSara Golemon <pollita@php.net>
Mon, 21 Jun 2004 21:08:05 +0000 (21:08 +0000)
filters which relates to the fix just applied for userspace wrappers.

ext/standard/basic_functions.c
ext/standard/file.h
ext/standard/user_filters.c
main/php_streams.h
main/streams/filter.c
main/streams/php_stream_filter_api.h
main/streams/streams.c

index 970c9628485081d43627d7d5ab37a71fbc03049e..3f1726c26d043e98fd56ab2651b590d4cd4d3022 100644 (file)
@@ -1163,6 +1163,9 @@ PHP_RINIT_FUNCTION(basic)
        /* Default to global wrappers only */
        FG(stream_wrappers) = NULL;
 
+       /* Default to global filters only */
+       FG(stream_filters) = NULL;
+
        return SUCCESS;
 }
 
@@ -1186,6 +1189,18 @@ PHP_RSHUTDOWN_FUNCTION(basic)
        }
        STR_FREE(BG(locale_string));
 
+       if (FG(stream_wrappers)) {
+               zend_hash_destroy(FG(stream_wrappers));
+               efree(FG(stream_wrappers));
+               FG(stream_wrappers) = NULL;
+       }
+
+       if (FG(stream_filters)) {
+               zend_hash_destroy(FG(stream_filters));
+               efree(FG(stream_filters));
+               FG(stream_filters) = NULL;
+       }
+
        PHP_RSHUTDOWN(filestat)(SHUTDOWN_FUNC_ARGS_PASSTHRU);
 #ifdef HAVE_SYSLOG_H
        PHP_RSHUTDOWN(syslog)(SHUTDOWN_FUNC_ARGS_PASSTHRU);
@@ -1200,12 +1215,6 @@ PHP_RSHUTDOWN_FUNCTION(basic)
                BG(user_tick_functions) = NULL;
        }
 
-       if (FG(stream_wrappers)) {
-               zend_hash_destroy(FG(stream_wrappers));
-               efree(FG(stream_wrappers));
-               FG(stream_wrappers) = NULL;
-       }
-
        PHP_RSHUTDOWN(user_filters)(SHUTDOWN_FUNC_ARGS_PASSTHRU);
        
        return SUCCESS;
index aba42e01bbe40615a17e9708aee6b055bc8369c2..e5c23e6a241274199b206430c1e4e08f08948437 100644 (file)
@@ -114,6 +114,7 @@ typedef struct {
        char *user_stream_current_filename; /* for simple recursion protection */
        php_stream_context *default_context;
        HashTable *stream_wrappers;                     /* per-request copy of url_stream_wrappers_hash */
+       HashTable *stream_filters;                      /* per-request copy of stream_filters_hash */
 } php_file_globals;
 
 #ifdef ZTS
index b67815d6630f3518abb2ff6ce87126b203a31923..e1ecf3c2060a6d2dcd82c2db31aa09e8a7478b82 100644 (file)
@@ -528,7 +528,7 @@ PHP_FUNCTION(stream_filter_register)
 
        if (zend_hash_add(BG(user_filter_map), filtername, filtername_len, (void*)fdat,
                                sizeof(*fdat) + classname_len, NULL) == SUCCESS &&
-                       php_stream_filter_register_factory(filtername, &user_filter_factory TSRMLS_CC) == SUCCESS) {
+                       php_stream_filter_register_factory_volatile(filtername, &user_filter_factory TSRMLS_CC) == SUCCESS) {
                RETVAL_TRUE;
        }
 
index f3461bbd7b9faf716637bb5a0b04021ce9757f95..000b4291c3ecf761d4b0ca7776664b53fd49e1b1 100755 (executable)
@@ -541,7 +541,9 @@ PHPAPI int _php_stream_make_seekable(php_stream *origstream, php_stream **newstr
 /* Give other modules access to the url_stream_wrappers_hash and stream_filters_hash */
 PHPAPI HashTable *_php_stream_get_url_stream_wrappers_hash(TSRMLS_D);
 #define php_stream_get_url_stream_wrappers_hash()      _php_stream_get_url_stream_wrappers_hash(TSRMLS_C)
-PHPAPI HashTable *php_get_stream_filters_hash();
+PHPAPI HashTable *_php_get_stream_filters_hash(TSRMLS_D);
+#define php_get_stream_filters_hash()  _php_get_stream_filters_hash(TSRMLS_C)
+PHPAPI HashTable *php_get_stream_filters_hash_global();
 END_EXTERN_C()
 #endif
 
index 8541e64c5f021a237864289bab833ea054eca472..cc6e62292fd945c17c71ca28be483cb82f818306 100644 (file)
 
 #include "php_streams_int.h"
 
+/* Global filter hash, copied to FG(stream_filters) on registration of volatile filter */
 static HashTable stream_filters_hash;
 
-PHPAPI HashTable *php_get_stream_filters_hash()
+/* Should only be used during core initialization */
+PHPAPI HashTable *php_get_stream_filters_hash_global()
 {
        return &stream_filters_hash;
 }
 
+/* Normal hash selection/retrieval call */
+PHPAPI HashTable *_php_get_stream_filters_hash(TSRMLS_D)
+{
+       return (FG(stream_filters) ? FG(stream_filters) : &stream_filters_hash);
+}
+
+/* API for registering GLOBAL filters */
 PHPAPI int php_stream_filter_register_factory(const char *filterpattern, php_stream_filter_factory *factory TSRMLS_DC)
 {
        return zend_hash_add(&stream_filters_hash, (char*)filterpattern, strlen(filterpattern), factory, sizeof(*factory), NULL);
@@ -45,6 +54,20 @@ PHPAPI int php_stream_filter_unregister_factory(const char *filterpattern TSRMLS
        return zend_hash_del(&stream_filters_hash, (char*)filterpattern, strlen(filterpattern));
 }
 
+/* API for registering VOLATILE wrappers */
+PHPAPI int php_stream_filter_register_factory_volatile(const char *filterpattern, php_stream_filter_factory *factory TSRMLS_DC)
+{
+       if (!FG(stream_filters)) {
+               php_stream_filter_factory tmpfactory;
+
+               FG(stream_filters) = emalloc(sizeof(HashTable));
+               zend_hash_init(FG(stream_filters), 0, NULL, NULL, 1);
+               zend_hash_copy(FG(stream_filters), &stream_filters_hash, NULL, &tmpfactory, sizeof(php_stream_filter_factory));
+       }
+
+       return zend_hash_add(FG(stream_filters), (char*)filterpattern, strlen(filterpattern), factory, sizeof(*factory), NULL);
+}
+
 /* Buckets */
 
 PHPAPI php_stream_bucket *php_stream_bucket_new(php_stream *stream, char *buf, size_t buflen, int own_buf, int buf_persistent TSRMLS_DC)
@@ -223,6 +246,7 @@ PHPAPI void php_stream_bucket_unlink(php_stream_bucket *bucket TSRMLS_DC)
  * charsets (for example) but still be able to provide them all as filters */
 PHPAPI php_stream_filter *php_stream_filter_create(const char *filtername, zval *filterparams, int persistent TSRMLS_DC)
 {
+       HashTable *filter_hash = (FG(stream_filters) ? FG(stream_filters) : &stream_filters_hash);
        php_stream_filter_factory *factory;
        php_stream_filter *filter = NULL;
        int n;
@@ -230,7 +254,7 @@ PHPAPI php_stream_filter *php_stream_filter_create(const char *filtername, zval
 
        n = strlen(filtername);
        
-       if (SUCCESS == zend_hash_find(&stream_filters_hash, (char*)filtername, n, (void**)&factory)) {
+       if (SUCCESS == zend_hash_find(filter_hash, (char*)filtername, n, (void**)&factory)) {
                filter = factory->create_filter(filtername, filterparams, persistent TSRMLS_CC);
        } else if ((period = strrchr(filtername, '.'))) {
                /* try a wildcard */
@@ -241,7 +265,7 @@ PHPAPI php_stream_filter *php_stream_filter_create(const char *filtername, zval
                while (period && !filter) {
                        *period = '\0';
                        strcat(wildname, ".*");
-                       if (SUCCESS == zend_hash_find(&stream_filters_hash, wildname, strlen(wildname), (void**)&factory)) {
+                       if (SUCCESS == zend_hash_find(filter_hash, wildname, strlen(wildname), (void**)&factory)) {
                                filter = factory->create_filter(filtername, filterparams, persistent TSRMLS_CC);
                        }
 
index 39237d5de85a681029f634426c6b0716ffe40630..733d1c52211efa21831d7c07802367443babe5d6 100644 (file)
@@ -141,6 +141,7 @@ typedef struct _php_stream_filter_factory {
 BEGIN_EXTERN_C()
 PHPAPI int php_stream_filter_register_factory(const char *filterpattern, php_stream_filter_factory *factory TSRMLS_DC);
 PHPAPI int php_stream_filter_unregister_factory(const char *filterpattern TSRMLS_DC);
+PHPAPI int php_stream_filter_register_factory_volatile(const char *filterpattern, php_stream_filter_factory *factory TSRMLS_DC);
 PHPAPI php_stream_filter *php_stream_filter_create(const char *filtername, zval *filterparams, int persistent TSRMLS_DC);
 END_EXTERN_C()
 
index 7b3439b4284deb3c61250cc5eac3fcc41529c163..46c5d16b2d0a8ded49d363b3b9bfafbdc3789080 100755 (executable)
@@ -1351,7 +1351,7 @@ int php_init_stream_wrappers(int module_number TSRMLS_DC)
        return (
                        zend_hash_init(&url_stream_wrappers_hash, 0, NULL, NULL, 1) == SUCCESS
                        && 
-                       zend_hash_init(php_get_stream_filters_hash(), 0, NULL, NULL, 1) == SUCCESS
+                       zend_hash_init(php_get_stream_filters_hash_global(), 0, NULL, NULL, 1) == SUCCESS
                        &&
                        zend_hash_init(php_stream_xport_get_hash(), 0, NULL, NULL, 1) == SUCCESS
                        &&