From: Sara Golemon Date: Fri, 10 Sep 2004 20:45:35 +0000 (+0000) Subject: Add stream_wrapper_unregister() X-Git-Tag: PRE_NEW_VM_GEN_PATCH~330 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=955b43ba129fabd10b7d7363a2d92d7ce9c4b228;p=php Add stream_wrapper_unregister() Disables a wrapper (user-defined or built-in) for the life of the request. Add stream_wrapper_restore() Restores the wrapper originally defined at the time the request started to the protocol name mentioned. --- diff --git a/NEWS b/NEWS index c189512900..eaa7887c1a 100644 --- a/NEWS +++ b/NEWS @@ -14,6 +14,8 @@ PHP NEWS . array_intersect_ukey() (Christiano Duarte) . stream_context_get_default() (Wez) . stream_socket_enable_crypto() (Wez) + . stream_wrapper_unregister() (Sara) + . stream_wrapper_restore() (Sara) . DomDocumentFragment->appendXML() (Christian) . SimpleXMLElement->registerXPathNamespace() (Christian) . mysqli->client_info property (Georg) diff --git a/ext/standard/basic_functions.c b/ext/standard/basic_functions.c index c52434ad35..3aa0eb25e4 100644 --- a/ext/standard/basic_functions.c +++ b/ext/standard/basic_functions.c @@ -623,6 +623,8 @@ function_entry basic_functions[] = { PHP_FE(stream_get_line, NULL) PHP_FE(stream_wrapper_register, NULL) PHP_FALIAS(stream_register_wrapper, stream_wrapper_register, NULL) + PHP_FE(stream_wrapper_unregister, NULL) + PHP_FE(stream_wrapper_restore, NULL) PHP_FE(stream_get_wrappers, NULL) PHP_FE(stream_get_transports, NULL) PHP_FE(get_headers, NULL) diff --git a/ext/standard/streamsfuncs.h b/ext/standard/streamsfuncs.h index 6ec9dba491..9b391b0c47 100644 --- a/ext/standard/streamsfuncs.h +++ b/ext/standard/streamsfuncs.h @@ -43,6 +43,8 @@ PHP_FUNCTION(stream_get_wrappers); PHP_FUNCTION(stream_get_line); PHP_FUNCTION(stream_get_meta_data); PHP_FUNCTION(stream_wrapper_register); +PHP_FUNCTION(stream_wrapper_unregister); +PHP_FUNCTION(stream_wrapper_restore); PHP_FUNCTION(stream_context_create); PHP_FUNCTION(stream_context_set_params); PHP_FUNCTION(stream_context_set_option); diff --git a/main/php_streams.h b/main/php_streams.h index 000b4291c3..290ec14e32 100755 --- a/main/php_streams.h +++ b/main/php_streams.h @@ -510,6 +510,7 @@ BEGIN_EXTERN_C() PHPAPI int php_register_url_stream_wrapper(char *protocol, php_stream_wrapper *wrapper TSRMLS_DC); PHPAPI int php_unregister_url_stream_wrapper(char *protocol TSRMLS_DC); PHPAPI int php_register_url_stream_wrapper_volatile(char *protocol, php_stream_wrapper *wrapper TSRMLS_DC); +PHPAPI int php_unregister_url_stream_wrapper_volatile(char *protocol TSRMLS_DC); PHPAPI php_stream *_php_stream_open_wrapper_ex(char *path, char *mode, int options, char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC); PHPAPI php_stream_wrapper *php_stream_locate_url_wrapper(const char *path, char **path_for_open, int options TSRMLS_DC); PHPAPI char *php_stream_locate_eol(php_stream *stream, char *buf, size_t buf_len TSRMLS_DC); @@ -541,6 +542,7 @@ 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_stream_get_url_stream_wrappers_hash_global(void); 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(); diff --git a/main/streams/streams.c b/main/streams/streams.c index fc5a0b82ee..0e73f320a6 100755 --- a/main/streams/streams.c +++ b/main/streams/streams.c @@ -54,6 +54,11 @@ PHPAPI HashTable *_php_stream_get_url_stream_wrappers_hash(TSRMLS_D) return (FG(stream_wrappers) ? FG(stream_wrappers) : &url_stream_wrappers_hash); } +PHPAPI HashTable *php_stream_get_url_stream_wrappers_hash_global(void) +{ + return &url_stream_wrappers_hash; +} + static int _php_stream_release_context(list_entry *le, void *pContext TSRMLS_DC) { if (le->ptr == pContext) { @@ -1417,6 +1422,18 @@ PHPAPI int php_register_url_stream_wrapper_volatile(char *protocol, php_stream_w return zend_hash_add(FG(stream_wrappers), protocol, strlen(protocol), wrapper, sizeof(*wrapper), NULL); } +PHPAPI int php_unregister_url_stream_wrapper_volatile(char *protocol TSRMLS_DC) +{ + if (!FG(stream_wrappers)) { + php_stream_wrapper tmpwrapper; + + FG(stream_wrappers) = emalloc(sizeof(HashTable)); + 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)); + } + + return zend_hash_del(FG(stream_wrappers), protocol, strlen(protocol)); +} /* }}} */ /* {{{ php_stream_locate_url_wrapper */ diff --git a/main/streams/userspace.c b/main/streams/userspace.c index 7bf7801d2f..0b68729092 100644 --- a/main/streams/userspace.c +++ b/main/streams/userspace.c @@ -437,6 +437,62 @@ PHP_FUNCTION(stream_wrapper_register) } /* }}} */ +/* {{{ bool stream_wrapper_unregister(string protocol) + Unregister a wrapper for the life of the current request. */ +PHP_FUNCTION(stream_wrapper_unregister) +{ + char *protocol; + int protocol_len; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &protocol, &protocol_len) == FAILURE) { + RETURN_FALSE; + } + + if (php_unregister_url_stream_wrapper_volatile(protocol TSRMLS_CC) == FAILURE) { + /* We failed */ + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to unregister protocol %s://", protocol); + RETURN_FALSE; + } + + RETURN_TRUE; +} +/* }}} */ + +/* {{{ bool stream_wrapper_restore(string protocol) + Restore the original protocol handler, overriding if necessary */ +PHP_FUNCTION(stream_wrapper_restore) +{ + char *protocol; + int protocol_len; + php_stream_wrapper *wrapper = NULL; + HashTable *global_wrapper_hash; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &protocol, &protocol_len) == FAILURE) { + RETURN_FALSE; + } + + global_wrapper_hash = php_stream_get_url_stream_wrappers_hash_global(); + if (php_stream_get_url_stream_wrappers_hash() == global_wrapper_hash) { + php_error_docref(NULL TSRMLS_CC, E_NOTICE, "%s:// was never changed, nothing to restore", protocol); + RETURN_TRUE; + } + + if ((zend_hash_find(global_wrapper_hash, protocol, protocol_len, (void**)&wrapper) == FAILURE) || !wrapper) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s:// never existed, nothing to restore", protocol); + RETURN_FALSE; + } + + /* A failure here could be okay given that the protocol might have been merely unregistered */ + php_unregister_url_stream_wrapper_volatile(protocol TSRMLS_CC); + + if (php_register_url_stream_wrapper_volatile(protocol, wrapper TSRMLS_CC) == FAILURE) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to restore original %s:// wrapper", protocol); + RETURN_FALSE; + } + + RETURN_TRUE; +} +/* }}} */ static size_t php_userstreamop_write(php_stream *stream, const char *buf, size_t count TSRMLS_DC) {