]> granicus.if.org Git - php/commitdiff
Fix segfault in wrapper error log mechanism when errors are logged on
authorWez Furlong <wez@php.net>
Thu, 26 Sep 2002 12:12:27 +0000 (12:12 +0000)
committerWez Furlong <wez@php.net>
Thu, 26 Sep 2002 12:12:27 +0000 (12:12 +0000)
second and subsequent events.
Implement very simple recursion protection for user streams written
like this:
class urlEncodeStream {
    var $fp = NULL;

    function stream_open($path, $mode, $options, &$opened_path)
    {
        $this->fp = fopen($path, $mode); // <-- this recurses infinitely
        return is_resource($this->fp);
    }
}

file_register_wrapper('urlencode', 'urlEncodeStream');
$fp = fopen('urlencode:///tmp/outputfile.txt', 'w');

Noticed by: Yasuo.

ext/standard/file.c
ext/standard/file.h
main/streams.c
main/user_streams.c

index b3d2fb539fc654a3bd188e3e438ec913dbb02cfd..38497a4a71e6245337ef7a9410a4eb4972a02ce5 100644 (file)
@@ -132,6 +132,7 @@ static ZEND_RSRC_DTOR_FUNC(file_context_dtor)
 static void file_globals_ctor(php_file_globals *file_globals_p TSRMLS_DC)
 {
        FG(pclose_ret) = 0;
+       FG(user_stream_current_filename) = NULL;
        FG(def_chunk_size) = PHP_SOCK_CHUNK_SIZE;
 }
 
index 3990504509ee3fcac45f507024ba678c6cf44b44..4e5eba55dd9b81aed3a2bf238094307d01bd1077 100644 (file)
@@ -115,6 +115,7 @@ typedef struct {
        int auto_detect_line_endings;
        int default_socket_timeout;
        char *user_agent;
+       char *user_stream_current_filename; /* for simple recursion protection */
 } php_file_globals;
 
 #ifdef ZTS
index fd222189013b75eff3653ff72f2d162e534159cd..ba8176dd6358d155b95ea97ac25595050a02fb41 100755 (executable)
@@ -1988,7 +1988,7 @@ PHPAPI php_stream *_php_stream_open_wrapper_ex(char *path, char *mode, int optio
                int free_msg = 0;
 
                if (wrapper) {
-                       if (wrapper->err_count) {
+                       if (wrapper->err_count > 0) {
                                int i;
                                size_t l;
                                int brlen;
@@ -2038,6 +2038,7 @@ PHPAPI php_stream *_php_stream_open_wrapper_ex(char *path, char *mode, int optio
                if (wrapper->err_stack)
                        efree(wrapper->err_stack);
                wrapper->err_stack = NULL;
+               wrapper->err_count = 0;
        }
 #if ZEND_DEBUG
        if (stream == NULL && copy_of_path != NULL)
index a6aff3cb8a13b5174cba79426962d97f9660f0b1..5c4ef63b921f03295ce2a119eee1547a9f066b52 100644 (file)
@@ -21,6 +21,7 @@
 
 #include "php.h"
 #include "php_globals.h"
+#include "ext/standard/file.h"
 
 static int le_protocols;
 
@@ -137,6 +138,13 @@ static php_stream *user_wrapper_opener(php_stream_wrapper *wrapper, char *filena
        int call_result;
        php_stream *stream = NULL;
 
+       /* Try to catch bad usage without prevent flexibility */
+       if (FG(user_stream_current_filename) != NULL && strcmp(filename, FG(user_stream_current_filename)) == 0) {
+               php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "infinite recursion prevented");
+               return NULL;
+       }
+       FG(user_stream_current_filename) = filename;
+       
        us = emalloc(sizeof(*us));
        us->wrapper = uwrap;    
 
@@ -206,6 +214,8 @@ static php_stream *user_wrapper_opener(php_stream_wrapper *wrapper, char *filena
        zval_ptr_dtor(&zmode);
        zval_ptr_dtor(&zfilename);
 
+       FG(user_stream_current_filename) = NULL;
+               
        return stream;
 }