Skip to content

Commit c5ca657

Browse files
committed
streams: refactor _php_stream_open_wrapper_ex() to use early returns
1 parent 36d8547 commit c5ca657

1 file changed

Lines changed: 91 additions & 57 deletions

File tree

main/streams/streams.c

Lines changed: 91 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -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);
2119+
}
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);
21212128
}
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,27 @@ 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+
if (options & REPORT_ERRORS) {
2239+
php_stream_display_wrapper_name_errors(wrapper_name, context, PHP_STREAM_EC(OpenFailed),
2240+
"Failed to open stream");
2241+
if (opened_path && *opened_path) {
2242+
zend_string_release_ex(*opened_path, 0);
2243+
*opened_path = NULL;
2244+
}
2245+
}
2246+
php_stream_tidy_wrapper_name_error_log(wrapper_name);
2247+
pefree(wrapper_name, persistent);
2248+
if (resolved_path) {
2249+
zend_string_release_ex(resolved_path, 0);
2250+
}
2251+
return NULL;
22092252
}
22102253
}
22112254

2212-
if (stream && stream->ops->seek && (stream->flags & PHP_STREAM_FLAG_NO_SEEK) == 0 && strchr(mode, 'a') && stream->position == 0) {
2255+
if (stream->ops->seek && (stream->flags & PHP_STREAM_FLAG_NO_SEEK) == 0 && strchr(mode, 'a') && stream->position == 0) {
22132256
zend_off_t newpos = 0;
22142257

22152258
/* if opened for append, we need to revise our idea of the initial file position */
@@ -2218,15 +2261,6 @@ PHPAPI php_stream *_php_stream_open_wrapper_ex(const char *path, const char *mod
22182261
}
22192262
}
22202263

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);
22302264
pefree(wrapper_name, persistent);
22312265
if (resolved_path) {
22322266
zend_string_release_ex(resolved_path, 0);

0 commit comments

Comments
 (0)