Browse files

Introduce an error stack for wrappers, to help prevent multiple errors

and warnings (some of which are bogus) when there are problems opening
streams.
Implement sanity check on the mode used to open ftp and http connections.
This fixes Bug 12004.
  • Loading branch information...
1 parent 1861f1b commit 5a21ab42cb0a7b4d0bc5661a6ae7d6ac085ed800 @wez wez committed Aug 11, 2002
Showing with 97 additions and 14 deletions.
  1. +4 −0 README.STREAMS
  2. +6 −1 ext/standard/ftp_fopen_wrapper.c
  3. +8 −6 ext/standard/http_fopen_wrapper.c
  4. +7 −0 main/php_streams.h
  5. +72 −7 main/streams.c
View
4 README.STREAMS
@@ -2,6 +2,10 @@ An Overview of the PHP Streams abstraction
==========================================
$Id$
+WARNING: some prototypes in this file are out of date.
+The information contained here is being integrated into
+the php manual - stay tuned...
+
Please send comments to: Wez Furlong <wez@thebrainroom.com>
Why Streams?
View
7 ext/standard/ftp_fopen_wrapper.c
@@ -115,6 +115,11 @@ php_stream * php_stream_url_wrap_ftp(php_stream_wrapper *wrapper, char *path, ch
int i;
char *tpath, *ttpath;
size_t file_size = 0;
+
+ if (strchr(mode, 'a') || strchr(mode, '+')) {
+ php_stream_wrapper_log_error(wrapper, options, "FTP does not support simultaneous read/write connections.");
+ return NULL;
+ }
resource = php_url_parse((char *) path);
if (resource == NULL || resource->path == NULL)
@@ -314,7 +319,7 @@ php_stream * php_stream_url_wrap_ftp(php_stream_wrapper *wrapper, char *path, ch
php_stream_close(stream);
}
if (tmp_line[0] != '\0')
- zend_error(E_WARNING, "FTP server reports %s", tmp_line);
+ php_stream_wrapper_log_error(wrapper, options, "FTP server reports %s", tmp_line);
return NULL;
}
/* }}} */
View
14 ext/standard/http_fopen_wrapper.c
@@ -86,11 +86,16 @@ php_stream *php_stream_url_wrap_http(php_stream_wrapper *wrapper, char *path, ch
char tmp_line[128];
size_t chunk_size = 0, file_size = 0;
+ if (strchr(mode, 'a') || strchr(mode, '+') || strchr(mode, 'w')) {
+ php_stream_wrapper_log_error(wrapper, options, "HTTP wrapper does not writeable connections.");
+ return NULL;
+ }
+
resource = php_url_parse(path);
if (resource == NULL)
return NULL;
- use_ssl = resource->scheme && resource->scheme[4] == 's';
+ use_ssl = resource->scheme && (strlen(resource->scheme) > 4) && resource->scheme[4] == 's';
/* choose default ports */
if (use_ssl && resource->port == 0)
@@ -113,9 +118,7 @@ php_stream *php_stream_url_wrap_http(php_stream_wrapper *wrapper, char *path, ch
#if HAVE_OPENSSL_EXT
if (use_ssl) {
if (php_stream_sock_ssl_activate(stream, 1) == FAILURE) {
- if (options & REPORT_ERRORS) {
- zend_error(E_WARNING, "Unable to activate SSL mode");
- }
+ php_stream_wrapper_log_error(wrapper, options, "Unable to activate SSL mode");
php_stream_close(stream);
stream = NULL;
goto out;
@@ -323,8 +326,7 @@ php_stream *php_stream_url_wrap_http(php_stream_wrapper *wrapper, char *path, ch
FREE_ZVAL(stream->wrapperdata);
}
} else {
- if (options & REPORT_ERRORS)
- zend_error(E_WARNING, "HTTP request failed! %s", tmp_line);
+ php_stream_wrapper_log_error(wrapper, options, "HTTP request failed! %s", tmp_line);
}
}
out:
View
7 main/php_streams.h
@@ -169,8 +169,15 @@ struct _php_stream_wrapper {
php_stream_wrapper_ops *wops; /* operations the wrapper can perform */
void *abstract; /* context for the wrapper */
int is_url; /* so that PG(allow_url_fopen) can be respected */
+
+ /* support for wrappers to return (multiple) error messages to the stream opener */
+ int err_count;
+ char **err_stack;
};
+/* pushes an error message onto the stack for a wrapper instance */
+PHPAPI void php_stream_wrapper_log_error(php_stream_wrapper *wrapper, int options TSRMLS_DC, const char *fmt, ...);
+
struct _php_stream {
php_stream_ops *ops;
void *abstract; /* convenience pointer for abstraction */
View
79 main/streams.c
@@ -1286,6 +1286,26 @@ PHPAPI php_stream_dirent *_php_stream_readdir(php_stream *dirstream, php_stream_
return NULL;
}
+PHPAPI void php_stream_wrapper_log_error(php_stream_wrapper *wrapper, int options TSRMLS_DC, const char *fmt, ...)
+{
+ va_list args;
+ char *buffer = NULL;
+
+ va_start(args, fmt);
+ vspprintf(&buffer, 0, fmt, args);
+ va_end(args);
+
+ if (options & REPORT_ERRORS || wrapper == NULL) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, buffer);
+ efree(buffer);
+ } else {
+ /* append to stack */
+ wrapper->err_stack = erealloc(wrapper->err_stack, (wrapper->err_count + 1) * sizeof(char *));
+ if (wrapper->err_stack)
+ wrapper->err_stack[wrapper->err_count++] = buffer;
+ }
+}
+
/* {{{ php_stream_open_wrapper_ex */
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)
@@ -1305,8 +1325,13 @@ PHPAPI php_stream *_php_stream_open_wrapper_ex(char *path, char *mode, int optio
wrapper = locate_url_wrapper(path, &path_to_open, options TSRMLS_CC);
if (wrapper) {
+
+ /* prepare error stack */
+ wrapper->err_count = 0;
+ wrapper->err_stack = NULL;
+
stream = wrapper->wops->stream_opener(wrapper,
- path_to_open, mode, options,
+ path_to_open, mode, options ^ REPORT_ERRORS,
opened_path, context STREAMS_REL_CC TSRMLS_CC);
if (stream)
stream->wrapper = wrapper;
@@ -1326,8 +1351,8 @@ PHPAPI php_stream *_php_stream_open_wrapper_ex(char *path, char *mode, int optio
if (options & REPORT_ERRORS) {
char *tmp = estrdup(path);
php_strip_url_passwd(tmp);
- zend_error(E_WARNING, "%s(\"%s\") - could not make seekable - %s",
- get_active_function_name(TSRMLS_C), tmp, strerror(errno));
+ php_error_docref1(NULL TSRMLS_CC, tmp, E_WARNING, "could not make seekable - %s",
+ tmp, strerror(errno));
efree(tmp);
options ^= REPORT_ERRORS;
@@ -1338,15 +1363,55 @@ PHPAPI php_stream *_php_stream_open_wrapper_ex(char *path, char *mode, int optio
char *tmp = estrdup(path);
char *msg;
- if (wrapper)
- msg = strerror(errno);
- else
+ if (wrapper) {
+ if (wrapper->err_count) {
+ int i;
+ size_t l;
+ int brlen;
+ char *br;
+
+ if (PG(html_errors)) {
+ brlen = 7;
+ br = "<br />\n";
+ } else {
+ brlen = 1;
+ br = "\n";
+ }
+
+ for (i = 0, l = 0; i < wrapper->err_count; i++) {
+ l += strlen(wrapper->err_stack[i]);
+ if (i < wrapper->err_count - 1)
+ l += brlen;
+ }
+ msg = emalloc(l + 1);
+ msg[0] = '\0';
+ for (i = 0; i < wrapper->err_count; i++) {
+ strcat(msg, wrapper->err_stack[i]);
+ if (i < wrapper->err_count - 1)
+ strcat(msg, br);
+ }
+
+ } else {
+ msg = strerror(errno);
+ }
+ } else {
msg = "no suitable wrapper could be found";
+ }
php_strip_url_passwd(tmp);
- zend_error(E_WARNING, "%s(\"%s\") - %s", get_active_function_name(TSRMLS_C), tmp, msg);
+ php_error_docref1(NULL TSRMLS_CC, tmp, E_WARNING, "failed to create stream: %s", msg);
efree(tmp);
}
+ if (wrapper) {
+ /* tidy up the error stack */
+ int i;
+
+ for (i = 0; i < wrapper->err_count; i++)
+ efree(wrapper->err_stack[i]);
+ if (wrapper->err_stack)
+ efree(wrapper->err_stack);
+ wrapper->err_stack = NULL;
+ }
return stream;
}
/* }}} */

0 comments on commit 5a21ab4

Please sign in to comment.