From 8663f1644da90e36b36004f0eeb1df1a24081a60 Mon Sep 17 00:00:00 2001 From: Wez Furlong Date: Sat, 22 Apr 2006 17:17:40 +0000 Subject: [PATCH] fix for #37158 --- NEWS | 2 ++ main/streams/php_streams_int.h | 1 - main/streams/streams.c | 43 +++++++++++++++++----------------- main/streams/userspace.c | 7 ++++-- 4 files changed, 29 insertions(+), 24 deletions(-) diff --git a/NEWS b/NEWS index 462775d6e50..0fc1432b0dc 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,8 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| 20 Apr 2006, PHP 5.1.3RC3 - Fixed reading stream filters never notified about EOF. (Mike) +- Fixed bug #37158 (fread behaviour changes after calling + stream_wrapper_register). (Wez) - Fixed bug #37138 (__autoload tries to load callback'ed self and parent). (Dmitry) - Fixed bug #37103 (libmbfl headers not installed). (Jani) diff --git a/main/streams/php_streams_int.h b/main/streams/php_streams_int.h index 96da8a0f1d2..8b83a77763e 100644 --- a/main/streams/php_streams_int.h +++ b/main/streams/php_streams_int.h @@ -46,7 +46,6 @@ #define STREAM_DEBUG 0 #define STREAM_WRAPPER_PLAIN_FILES ((php_stream_wrapper*)-1) -extern php_stream_wrapper php_plain_files_wrapper; #ifndef MAP_FAILED #define MAP_FAILED ((void *) -1) diff --git a/main/streams/streams.c b/main/streams/streams.c index af3deaa5c00..2548f4d650b 100755 --- a/main/streams/streams.c +++ b/main/streams/streams.c @@ -1457,7 +1457,7 @@ PHPAPI int php_register_url_stream_wrapper(char *protocol, php_stream_wrapper *w return FAILURE; } - return zend_hash_add(&url_stream_wrappers_hash, protocol, protocol_len, wrapper, sizeof(*wrapper), NULL); + return zend_hash_add(&url_stream_wrappers_hash, protocol, protocol_len, &wrapper, sizeof(wrapper), NULL); } PHPAPI int php_unregister_url_stream_wrapper(char *protocol TSRMLS_DC) @@ -1465,6 +1465,15 @@ PHPAPI int php_unregister_url_stream_wrapper(char *protocol TSRMLS_DC) return zend_hash_del(&url_stream_wrappers_hash, protocol, strlen(protocol)); } +static void clone_wrapper_hash(TSRMLS_D) +{ + php_stream_wrapper *tmp; + + ALLOC_HASHTABLE(FG(stream_wrappers)); + zend_hash_init(FG(stream_wrappers), 0, NULL, NULL, 1); + zend_hash_copy(FG(stream_wrappers), &url_stream_wrappers_hash, NULL, &tmp, sizeof(tmp)); +} + /* API for registering VOLATILE wrappers */ PHPAPI int php_register_url_stream_wrapper_volatile(char *protocol, php_stream_wrapper *wrapper TSRMLS_DC) { @@ -1475,24 +1484,16 @@ PHPAPI int php_register_url_stream_wrapper_volatile(char *protocol, php_stream_w } if (!FG(stream_wrappers)) { - php_stream_wrapper tmpwrapper; - - ALLOC_HASHTABLE(FG(stream_wrappers)); - zend_hash_init(FG(stream_wrappers), 0, NULL, NULL, 1); - zend_hash_copy(FG(stream_wrappers), &url_stream_wrappers_hash, NULL, &tmpwrapper, sizeof(php_stream_wrapper)); + clone_wrapper_hash(TSRMLS_C); } - return zend_hash_add(FG(stream_wrappers), protocol, protocol_len, wrapper, sizeof(*wrapper), NULL); + return zend_hash_add(FG(stream_wrappers), protocol, protocol_len, &wrapper, sizeof(wrapper), NULL); } PHPAPI int php_unregister_url_stream_wrapper_volatile(char *protocol TSRMLS_DC) { if (!FG(stream_wrappers)) { - php_stream_wrapper tmpwrapper; - - ALLOC_HASHTABLE(FG(stream_wrappers)); - zend_hash_init(FG(stream_wrappers), 0, NULL, NULL, 1); - zend_hash_copy(FG(stream_wrappers), &url_stream_wrappers_hash, NULL, &tmpwrapper, sizeof(php_stream_wrapper)); + clone_wrapper_hash(TSRMLS_C); } return zend_hash_del(FG(stream_wrappers), protocol, strlen(protocol)); @@ -1503,7 +1504,7 @@ PHPAPI int php_unregister_url_stream_wrapper_volatile(char *protocol TSRMLS_DC) PHPAPI php_stream_wrapper *php_stream_locate_url_wrapper(const char *path, char **path_for_open, int options TSRMLS_DC) { HashTable *wrapper_hash = (FG(stream_wrappers) ? FG(stream_wrappers) : &url_stream_wrappers_hash); - php_stream_wrapper *wrapper = NULL; + php_stream_wrapper **wrapperpp = NULL; const char *p, *protocol = NULL; int n = 0; @@ -1529,7 +1530,7 @@ PHPAPI php_stream_wrapper *php_stream_locate_url_wrapper(const char *path, char } if (protocol) { - if (FAILURE == zend_hash_find(wrapper_hash, (char*)protocol, n, (void**)&wrapper)) { + if (FAILURE == zend_hash_find(wrapper_hash, (char*)protocol, n, (void**)&wrapperpp)) { char wrapper_name[32]; if (n >= sizeof(wrapper_name)) @@ -1539,7 +1540,7 @@ PHPAPI php_stream_wrapper *php_stream_locate_url_wrapper(const char *path, char php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Unable to find the wrapper \"%s\" - did you forget to enable it when you configured PHP?", wrapper_name); - wrapper = NULL; + wrapperpp = NULL; protocol = NULL; } } @@ -1584,14 +1585,14 @@ PHPAPI php_stream_wrapper *php_stream_locate_url_wrapper(const char *path, char if (FG(stream_wrappers)) { /* The file:// wrapper may have been disabled/overridden */ - if (wrapper) { + if (wrapperpp) { /* It was found so go ahead and provide it */ - return wrapper; + return *wrapperpp; } /* Check again, the original check might have not known the protocol name */ - if (zend_hash_find(wrapper_hash, "file", sizeof("file")-1, (void**)&wrapper) == SUCCESS) { - return wrapper; + if (zend_hash_find(wrapper_hash, "file", sizeof("file")-1, (void**)&wrapperpp) == SUCCESS) { + return *wrapperpp; } if (options & REPORT_ERRORS) { @@ -1604,14 +1605,14 @@ PHPAPI php_stream_wrapper *php_stream_locate_url_wrapper(const char *path, char return &php_plain_files_wrapper; } - if (wrapper && wrapper->is_url && !PG(allow_url_fopen)) { + if (wrapperpp && (*wrapperpp)->is_url && !PG(allow_url_fopen)) { if (options & REPORT_ERRORS) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "URL file-access is disabled in the server configuration"); } return NULL; } - return wrapper; + return *wrapperpp; } /* }}} */ diff --git a/main/streams/userspace.c b/main/streams/userspace.c index eeeb7140c7e..5091dfdbe98 100644 --- a/main/streams/userspace.c +++ b/main/streams/userspace.c @@ -464,7 +464,7 @@ PHP_FUNCTION(stream_wrapper_restore) { char *protocol; int protocol_len; - php_stream_wrapper *wrapper = NULL; + php_stream_wrapper **wrapperpp = NULL, *wrapper; HashTable *global_wrapper_hash; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &protocol, &protocol_len) == FAILURE) { @@ -477,11 +477,14 @@ PHP_FUNCTION(stream_wrapper_restore) RETURN_TRUE; } - if ((zend_hash_find(global_wrapper_hash, protocol, protocol_len, (void**)&wrapper) == FAILURE) || !wrapper) { + if ((zend_hash_find(global_wrapper_hash, protocol, protocol_len, (void**)&wrapperpp) == FAILURE) || !wrapperpp) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s:// never existed, nothing to restore", protocol); RETURN_FALSE; } + /* next line might delete the pointer that wrapperpp points at, so deref it now */ + wrapper = *wrapperpp; + /* A failure here could be okay given that the protocol might have been merely unregistered */ php_unregister_url_stream_wrapper_volatile(protocol TSRMLS_CC);