diff options
author | Sara Golemon <pollita@php.net> | 2004-06-21 21:08:05 +0000 |
---|---|---|
committer | Sara Golemon <pollita@php.net> | 2004-06-21 21:08:05 +0000 |
commit | a2c24ae90ead95f8dbed95ff732e6c89bd4275b4 (patch) | |
tree | 33f37635e277b9ea2cc75997de9229d66a464814 | |
parent | dc66fb1f10518b1c4712fd4d253ab3fb61428080 (diff) | |
download | php-git-a2c24ae90ead95f8dbed95ff732e6c89bd4275b4.tar.gz |
BugFix#28868 (Part Two): This fixes thread unsafety in the userspace
filters which relates to the fix just applied for userspace wrappers.
-rw-r--r-- | ext/standard/basic_functions.c | 21 | ||||
-rw-r--r-- | ext/standard/file.h | 1 | ||||
-rw-r--r-- | ext/standard/user_filters.c | 2 | ||||
-rwxr-xr-x | main/php_streams.h | 4 | ||||
-rw-r--r-- | main/streams/filter.c | 30 | ||||
-rw-r--r-- | main/streams/php_stream_filter_api.h | 1 | ||||
-rwxr-xr-x | main/streams/streams.c | 2 |
7 files changed, 49 insertions, 12 deletions
diff --git a/ext/standard/basic_functions.c b/ext/standard/basic_functions.c index 970c962848..3f1726c26d 100644 --- a/ext/standard/basic_functions.c +++ b/ext/standard/basic_functions.c @@ -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; diff --git a/ext/standard/file.h b/ext/standard/file.h index aba42e01bb..e5c23e6a24 100644 --- a/ext/standard/file.h +++ b/ext/standard/file.h @@ -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 diff --git a/ext/standard/user_filters.c b/ext/standard/user_filters.c index b67815d663..e1ecf3c206 100644 --- a/ext/standard/user_filters.c +++ b/ext/standard/user_filters.c @@ -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; } diff --git a/main/php_streams.h b/main/php_streams.h index f3461bbd7b..000b4291c3 100755 --- a/main/php_streams.h +++ b/main/php_streams.h @@ -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 diff --git a/main/streams/filter.c b/main/streams/filter.c index 8541e64c5f..cc6e62292f 100644 --- a/main/streams/filter.c +++ b/main/streams/filter.c @@ -28,13 +28,22 @@ #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); } diff --git a/main/streams/php_stream_filter_api.h b/main/streams/php_stream_filter_api.h index 39237d5de8..733d1c5221 100644 --- a/main/streams/php_stream_filter_api.h +++ b/main/streams/php_stream_filter_api.h @@ -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() diff --git a/main/streams/streams.c b/main/streams/streams.c index 7b3439b428..46c5d16b2d 100755 --- a/main/streams/streams.c +++ b/main/streams/streams.c @@ -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 && |