]> granicus.if.org Git - php/commitdiff
Introduce an error stack for wrappers, to help prevent multiple errors
authorWez Furlong <wez@php.net>
Sun, 11 Aug 2002 10:53:10 +0000 (10:53 +0000)
committerWez Furlong <wez@php.net>
Sun, 11 Aug 2002 10:53:10 +0000 (10:53 +0000)
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.

README.STREAMS
ext/standard/ftp_fopen_wrapper.c
ext/standard/http_fopen_wrapper.c
main/php_streams.h
main/streams.c

index 870888a6bcbe3e01888298303bb5dc928f85f3d2..91a9245c0a785a43b30803c529a75462f4de4342 100644 (file)
@@ -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?
index 9bbdbedee43097a99b90f47a8c275cc076839eed..b5d3ccdc16f43800827ce3cf8fd1b6dfb606b089 100644 (file)
@@ -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;
 }
 /* }}} */
index 3a2aa8e57e9f774730d3fa5fcdde66d3a471922b..c06dc6210c47341fe198aa5d1b56ed25b17e4b01 100644 (file)
@@ -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:
index d50b8135c4423d2892d2ce86f3728391d73c4c91..160d73393109ab44cdaf70ccda6081f5bcdfb230 100755 (executable)
@@ -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 */
index 318c815bccee62cca36c9aff2086fda4ef5f8b0b..931e331457ec424122496a907caaac453927fe93 100755 (executable)
@@ -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;
 }
 /* }}} */