@@ -2111,14 +2111,28 @@ PHPAPI php_stream *_php_stream_open_wrapper_ex(const char *path, const char *mod
21112111 path_to_open = path ;
21122112
21132113 wrapper = php_stream_locate_url_wrapper (path , & path_to_open , options );
2114- if ((options & STREAM_USE_URL ) && (!wrapper || !wrapper -> is_url )) {
2115- if (wrapper ) {
2116- php_stream_wrapper_warn (wrapper , context , options ,
2117- ProtocolUnsupported ,
2118- "This function may only be used against URLs" );
2119- } else {
2120- php_error_docref (NULL , E_WARNING , "This function may only be used against URLs" );
2114+ if (UNEXPECTED (!wrapper )) {
2115+ php_stream_wrapper_warn_name (PHP_STREAM_ERROR_WRAPPER_DEFAULT_NAME , context , options , OpenFailed ,
2116+ "Failed to open stream: no suitable wrapper could be found" );
2117+ if (resolved_path ) {
2118+ zend_string_release_ex (resolved_path , 0 );
21212119 }
2120+ return NULL ;
2121+ }
2122+ if ((options & STREAM_USE_URL ) && !wrapper -> is_url ) {
2123+ php_stream_wrapper_warn (wrapper , context , options ,
2124+ ProtocolUnsupported ,
2125+ "This function may only be used against URLs" );
2126+ if (resolved_path ) {
2127+ zend_string_release_ex (resolved_path , 0 );
2128+ }
2129+ return NULL ;
2130+ }
2131+
2132+ if (!wrapper -> wops -> stream_opener ) {
2133+ php_stream_wrapper_warn (wrapper , context , options ,
2134+ NoOpener ,
2135+ "wrapper does not support stream open" );
21222136 if (resolved_path ) {
21232137 zend_string_release_ex (resolved_path , 0 );
21242138 }
@@ -2127,56 +2141,74 @@ PHPAPI php_stream *_php_stream_open_wrapper_ex(const char *path, const char *mod
21272141
21282142 /* wrapper name needs to be stored as wrapper can be removed in opener (user stream) */
21292143 char * wrapper_name = pestrdup (PHP_STREAM_ERROR_WRAPPER_NAME (wrapper ), persistent );
2130- if (wrapper ) {
2131- if (!wrapper -> wops -> stream_opener ) {
2132- php_stream_wrapper_log_warn (wrapper , context , options & ~REPORT_ERRORS ,
2133- NoOpener ,
2134- "wrapper does not support stream open" );
2135- } else {
2136- stream = wrapper -> wops -> stream_opener (wrapper ,
2137- path_to_open , mode , options & ~REPORT_ERRORS ,
2138- opened_path , context STREAMS_REL_CC );
2139- }
2144+ stream = wrapper -> wops -> stream_opener (wrapper ,
2145+ path_to_open , mode , options & ~REPORT_ERRORS ,
2146+ opened_path , context STREAMS_REL_CC );
21402147
2141- /* if the caller asked for a persistent stream but the wrapper did not
2142- * return one, force an error here */
2143- if ( stream && persistent && ! stream -> is_persistent ) {
2144- php_stream_wrapper_log_warn ( wrapper , context , options & ~ REPORT_ERRORS ,
2145- PersistentNotSupported ,
2146- "wrapper does not support persistent streams" );
2147- php_stream_close ( stream ) ;
2148- stream = NULL ;
2148+ if ( UNEXPECTED (! stream )) {
2149+ if ( options & REPORT_ERRORS ) {
2150+ php_stream_display_wrapper_name_errors ( wrapper_name , context , PHP_STREAM_EC ( OpenFailed ),
2151+ "Failed to open stream" );
2152+ if ( opened_path && * opened_path ) {
2153+ zend_string_release_ex ( * opened_path , 0 );
2154+ * opened_path = NULL ;
2155+ }
21492156 }
2150-
2151- if (stream ) {
2152- stream -> wrapper = wrapper ;
2157+ php_stream_tidy_wrapper_name_error_log (wrapper_name );
2158+ pefree (wrapper_name , persistent );
2159+ if (resolved_path ) {
2160+ zend_string_release_ex (resolved_path , 0 );
21532161 }
2162+ return NULL ;
21542163 }
21552164
2156- if (stream ) {
2157- if (opened_path && !* opened_path && resolved_path ) {
2158- * opened_path = resolved_path ;
2159- resolved_path = NULL ;
2165+ /* if the caller asked for a persistent stream but the wrapper did not
2166+ * return one, force an error here */
2167+ if (persistent && !stream -> is_persistent ) {
2168+ php_stream_wrapper_log_warn (wrapper , context , options & ~REPORT_ERRORS ,
2169+ PersistentNotSupported ,
2170+ "wrapper does not support persistent streams" );
2171+ php_stream_close (stream );
2172+ if (options & REPORT_ERRORS ) {
2173+ php_stream_display_wrapper_name_errors (wrapper_name , context , PHP_STREAM_EC (OpenFailed ),
2174+ "Failed to open stream" );
2175+ if (opened_path && * opened_path ) {
2176+ zend_string_release_ex (* opened_path , 0 );
2177+ * opened_path = NULL ;
2178+ }
21602179 }
2161- if (stream -> orig_path ) {
2162- pefree (stream -> orig_path , persistent );
2180+ php_stream_tidy_wrapper_name_error_log (wrapper_name );
2181+ pefree (wrapper_name , persistent );
2182+ if (resolved_path ) {
2183+ zend_string_release_ex (resolved_path , 0 );
21632184 }
2164- stream -> orig_path = pestrdup (path , persistent );
2185+ return NULL ;
2186+ }
2187+
2188+ stream -> wrapper = wrapper ;
2189+
2190+ if (opened_path && !* opened_path && resolved_path ) {
2191+ * opened_path = resolved_path ;
2192+ resolved_path = NULL ;
2193+ }
2194+ if (stream -> orig_path ) {
2195+ pefree (stream -> orig_path , persistent );
2196+ }
2197+ stream -> orig_path = pestrdup (path , persistent );
21652198#if ZEND_DEBUG
21662199 stream -> open_filename = __zend_orig_filename ? __zend_orig_filename : __zend_filename ;
21672200 stream -> open_lineno = __zend_orig_lineno ? __zend_orig_lineno : __zend_lineno ;
21682201#endif
2169- /* Attach an explicitly provided context to the stream, but never the
2170- * default context: sharing it by reference would let a later
2171- * stream_context_set_option() on the stream mutate the global default
2172- * context, leaking options into every other stream. Stream errors fall
2173- * back to the default context on their own when the stream has none. */
2174- if (stream -> ctx == NULL && context != NULL && context != FG (default_context ) && !persistent ) {
2175- php_stream_context_set (stream , context );
2176- }
2202+ /* Attach an explicitly provided context to the stream, but never the
2203+ * default context: sharing it by reference would let a later
2204+ * stream_context_set_option() on the stream mutate the global default
2205+ * context, leaking options into every other stream. Stream errors fall
2206+ * back to the default context on their own when the stream has none. */
2207+ if (stream -> ctx == NULL && context != NULL && context != FG (default_context ) && !persistent ) {
2208+ php_stream_context_set (stream , context );
21772209 }
21782210
2179- if (stream != NULL && ( options & STREAM_MUST_SEEK ) ) {
2211+ if (options & STREAM_MUST_SEEK ) {
21802212 php_stream * newstream ;
21812213
21822214 switch (php_stream_make_seekable_rel (stream , & newstream ,
@@ -2200,16 +2232,19 @@ PHPAPI php_stream *_php_stream_open_wrapper_ex(const char *path, const char *mod
22002232 return newstream ;
22012233 default :
22022234 php_stream_close (stream );
2203- stream = NULL ;
22042235 php_stream_wrapper_warn (wrapper , context , options ,
22052236 SeekNotSupported ,
22062237 "could not make seekable - %s" , path );
2207- /* We do not want multiple errors so we negate it */
2208- options &= ~REPORT_ERRORS ;
2238+ php_stream_tidy_wrapper_name_error_log (wrapper_name );
2239+ pefree (wrapper_name , persistent );
2240+ if (resolved_path ) {
2241+ zend_string_release_ex (resolved_path , 0 );
2242+ }
2243+ return NULL ;
22092244 }
22102245 }
22112246
2212- if (stream && stream -> ops -> seek && (stream -> flags & PHP_STREAM_FLAG_NO_SEEK ) == 0 && strchr (mode , 'a' ) && stream -> position == 0 ) {
2247+ if (stream -> ops -> seek && (stream -> flags & PHP_STREAM_FLAG_NO_SEEK ) == 0 && strchr (mode , 'a' ) && stream -> position == 0 ) {
22132248 zend_off_t newpos = 0 ;
22142249
22152250 /* if opened for append, we need to revise our idea of the initial file position */
@@ -2218,15 +2253,6 @@ PHPAPI php_stream *_php_stream_open_wrapper_ex(const char *path, const char *mod
22182253 }
22192254 }
22202255
2221- if (stream == NULL && (options & REPORT_ERRORS )) {
2222- php_stream_display_wrapper_name_errors (wrapper_name , context , PHP_STREAM_EC (OpenFailed ),
2223- "Failed to open stream" );
2224- if (opened_path && * opened_path ) {
2225- zend_string_release_ex (* opened_path , 0 );
2226- * opened_path = NULL ;
2227- }
2228- }
2229- php_stream_tidy_wrapper_name_error_log (wrapper_name );
22302256 pefree (wrapper_name , persistent );
22312257 if (resolved_path ) {
22322258 zend_string_release_ex (resolved_path , 0 );
0 commit comments