@@ -2118,14 +2118,28 @@ PHPAPI php_stream *_php_stream_open_wrapper_ex(const char *path, const char *mod
21182118 path_to_open = path ;
21192119
21202120 wrapper = php_stream_locate_url_wrapper (path , & path_to_open , options );
2121- if ((options & STREAM_USE_URL ) && (!wrapper || !wrapper -> is_url )) {
2122- if (wrapper ) {
2123- php_stream_wrapper_warn (wrapper , context , options ,
2124- ProtocolUnsupported ,
2125- "This function may only be used against URLs" );
2126- } else {
2127- php_error_docref (NULL , E_WARNING , "This function may only be used against URLs" );
2121+ if (UNEXPECTED (!wrapper )) {
2122+ php_stream_wrapper_warn_name (PHP_STREAM_ERROR_WRAPPER_DEFAULT_NAME , context , options , OpenFailed ,
2123+ "Failed to open stream: no suitable wrapper could be found" );
2124+ if (resolved_path ) {
2125+ zend_string_release_ex (resolved_path , 0 );
2126+ }
2127+ return NULL ;
2128+ }
2129+ if ((options & STREAM_USE_URL ) && !wrapper -> is_url ) {
2130+ php_stream_wrapper_warn (wrapper , context , options ,
2131+ ProtocolUnsupported ,
2132+ "This function may only be used against URLs" );
2133+ if (resolved_path ) {
2134+ zend_string_release_ex (resolved_path , 0 );
21282135 }
2136+ return NULL ;
2137+ }
2138+
2139+ if (!wrapper -> wops -> stream_opener ) {
2140+ php_stream_wrapper_warn (wrapper , context , options ,
2141+ NoOpener ,
2142+ "wrapper does not support stream open" );
21292143 if (resolved_path ) {
21302144 zend_string_release_ex (resolved_path , 0 );
21312145 }
@@ -2134,56 +2148,74 @@ PHPAPI php_stream *_php_stream_open_wrapper_ex(const char *path, const char *mod
21342148
21352149 /* wrapper name needs to be stored as wrapper can be removed in opener (user stream) */
21362150 char * wrapper_name = pestrdup (PHP_STREAM_ERROR_WRAPPER_NAME (wrapper ), persistent );
2137- if (wrapper ) {
2138- if (!wrapper -> wops -> stream_opener ) {
2139- php_stream_wrapper_log_warn (wrapper , context , options & ~REPORT_ERRORS ,
2140- NoOpener ,
2141- "wrapper does not support stream open" );
2142- } else {
2143- stream = wrapper -> wops -> stream_opener (wrapper ,
2144- path_to_open , mode , options & ~REPORT_ERRORS ,
2145- opened_path , context STREAMS_REL_CC );
2146- }
2151+ stream = wrapper -> wops -> stream_opener (wrapper ,
2152+ path_to_open , mode , options & ~REPORT_ERRORS ,
2153+ opened_path , context STREAMS_REL_CC );
21472154
2148- /* if the caller asked for a persistent stream but the wrapper did not
2149- * return one, force an error here */
2150- if ( stream && persistent && ! stream -> is_persistent ) {
2151- php_stream_wrapper_log_warn ( wrapper , context , options & ~ REPORT_ERRORS ,
2152- PersistentNotSupported ,
2153- "wrapper does not support persistent streams" );
2154- php_stream_close ( stream ) ;
2155- stream = NULL ;
2155+ if ( UNEXPECTED (! stream )) {
2156+ if ( options & REPORT_ERRORS ) {
2157+ php_stream_display_wrapper_name_errors ( wrapper_name , context , PHP_STREAM_EC ( OpenFailed ),
2158+ "Failed to open stream" );
2159+ if ( opened_path && * opened_path ) {
2160+ zend_string_release_ex ( * opened_path , 0 );
2161+ * opened_path = NULL ;
2162+ }
21562163 }
2157-
2158- if (stream ) {
2159- stream -> wrapper = wrapper ;
2164+ php_stream_tidy_wrapper_name_error_log (wrapper_name );
2165+ pefree (wrapper_name , persistent );
2166+ if (resolved_path ) {
2167+ zend_string_release_ex (resolved_path , 0 );
21602168 }
2169+ return NULL ;
21612170 }
21622171
2163- if (stream ) {
2164- if (opened_path && !* opened_path && resolved_path ) {
2165- * opened_path = resolved_path ;
2166- resolved_path = NULL ;
2172+ /* if the caller asked for a persistent stream but the wrapper did not
2173+ * return one, force an error here */
2174+ if (persistent && !stream -> is_persistent ) {
2175+ php_stream_wrapper_log_warn (wrapper , context , options & ~REPORT_ERRORS ,
2176+ PersistentNotSupported ,
2177+ "wrapper does not support persistent streams" );
2178+ php_stream_close (stream );
2179+ if (options & REPORT_ERRORS ) {
2180+ php_stream_display_wrapper_name_errors (wrapper_name , context , PHP_STREAM_EC (OpenFailed ),
2181+ "Failed to open stream" );
2182+ if (opened_path && * opened_path ) {
2183+ zend_string_release_ex (* opened_path , 0 );
2184+ * opened_path = NULL ;
2185+ }
21672186 }
2168- if (stream -> orig_path ) {
2169- pefree (stream -> orig_path , persistent );
2187+ php_stream_tidy_wrapper_name_error_log (wrapper_name );
2188+ pefree (wrapper_name , persistent );
2189+ if (resolved_path ) {
2190+ zend_string_release_ex (resolved_path , 0 );
21702191 }
2171- stream -> orig_path = pestrdup (path , persistent );
2192+ return NULL ;
2193+ }
2194+
2195+ stream -> wrapper = wrapper ;
2196+
2197+ if (opened_path && !* opened_path && resolved_path ) {
2198+ * opened_path = resolved_path ;
2199+ resolved_path = NULL ;
2200+ }
2201+ if (stream -> orig_path ) {
2202+ pefree (stream -> orig_path , persistent );
2203+ }
2204+ stream -> orig_path = pestrdup (path , persistent );
21722205#if ZEND_DEBUG
21732206 stream -> open_filename = __zend_orig_filename ? __zend_orig_filename : __zend_filename ;
21742207 stream -> open_lineno = __zend_orig_lineno ? __zend_orig_lineno : __zend_lineno ;
21752208#endif
2176- /* Attach an explicitly provided context to the stream, but never the
2177- * default context: sharing it by reference would let a later
2178- * stream_context_set_option() on the stream mutate the global default
2179- * context, leaking options into every other stream. Stream errors fall
2180- * back to the default context on their own when the stream has none. */
2181- if (stream -> ctx == NULL && context != NULL && context != FG (default_context ) && !persistent ) {
2182- php_stream_context_set (stream , context );
2183- }
2209+ /* Attach an explicitly provided context to the stream, but never the
2210+ * default context: sharing it by reference would let a later
2211+ * stream_context_set_option() on the stream mutate the global default
2212+ * context, leaking options into every other stream. Stream errors fall
2213+ * back to the default context on their own when the stream has none. */
2214+ if (stream -> ctx == NULL && context != NULL && context != FG (default_context ) && !persistent ) {
2215+ php_stream_context_set (stream , context );
21842216 }
21852217
2186- if (stream != NULL && ( options & STREAM_MUST_SEEK ) ) {
2218+ if (options & STREAM_MUST_SEEK ) {
21872219 php_stream * newstream ;
21882220
21892221 switch (php_stream_make_seekable_rel (stream , & newstream ,
@@ -2207,16 +2239,19 @@ PHPAPI php_stream *_php_stream_open_wrapper_ex(const char *path, const char *mod
22072239 return newstream ;
22082240 default :
22092241 php_stream_close (stream );
2210- stream = NULL ;
22112242 php_stream_wrapper_warn (wrapper , context , options ,
22122243 SeekNotSupported ,
22132244 "could not make seekable - %s" , path );
2214- /* We do not want multiple errors so we negate it */
2215- options &= ~REPORT_ERRORS ;
2245+ php_stream_tidy_wrapper_name_error_log (wrapper_name );
2246+ pefree (wrapper_name , persistent );
2247+ if (resolved_path ) {
2248+ zend_string_release_ex (resolved_path , 0 );
2249+ }
2250+ return NULL ;
22162251 }
22172252 }
22182253
2219- if (stream && stream -> ops -> seek && (stream -> flags & PHP_STREAM_FLAG_NO_SEEK ) == 0 && strchr (mode , 'a' ) && stream -> position == 0 ) {
2254+ if (stream -> ops -> seek && (stream -> flags & PHP_STREAM_FLAG_NO_SEEK ) == 0 && strchr (mode , 'a' ) && stream -> position == 0 ) {
22202255 zend_off_t newpos = 0 ;
22212256
22222257 /* if opened for append, we need to revise our idea of the initial file position */
@@ -2225,15 +2260,6 @@ PHPAPI php_stream *_php_stream_open_wrapper_ex(const char *path, const char *mod
22252260 }
22262261 }
22272262
2228- if (stream == NULL && (options & REPORT_ERRORS )) {
2229- php_stream_display_wrapper_name_errors (wrapper_name , context , PHP_STREAM_EC (OpenFailed ),
2230- "Failed to open stream" );
2231- if (opened_path && * opened_path ) {
2232- zend_string_release_ex (* opened_path , 0 );
2233- * opened_path = NULL ;
2234- }
2235- }
2236- php_stream_tidy_wrapper_name_error_log (wrapper_name );
22372263 pefree (wrapper_name , persistent );
22382264 if (resolved_path ) {
22392265 zend_string_release_ex (resolved_path , 0 );
0 commit comments