Fix segfault in wrapper error log mechanism when errors are logged on

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.
This commit is contained in:
Wez Furlong 2002-09-26 12:12:27 +00:00
parent 1f227cd2e3
commit c484eb8c97
4 changed files with 14 additions and 1 deletions

View 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) static void file_globals_ctor(php_file_globals *file_globals_p TSRMLS_DC)
{ {
FG(pclose_ret) = 0; FG(pclose_ret) = 0;
FG(user_stream_current_filename) = NULL;
FG(def_chunk_size) = PHP_SOCK_CHUNK_SIZE; FG(def_chunk_size) = PHP_SOCK_CHUNK_SIZE;
} }

View file

@ -115,6 +115,7 @@ typedef struct {
int auto_detect_line_endings; int auto_detect_line_endings;
int default_socket_timeout; int default_socket_timeout;
char *user_agent; char *user_agent;
char *user_stream_current_filename; /* for simple recursion protection */
} php_file_globals; } php_file_globals;
#ifdef ZTS #ifdef ZTS

View file

@ -1988,7 +1988,7 @@ PHPAPI php_stream *_php_stream_open_wrapper_ex(char *path, char *mode, int optio
int free_msg = 0; int free_msg = 0;
if (wrapper) { if (wrapper) {
if (wrapper->err_count) { if (wrapper->err_count > 0) {
int i; int i;
size_t l; size_t l;
int brlen; int brlen;
@ -2038,6 +2038,7 @@ PHPAPI php_stream *_php_stream_open_wrapper_ex(char *path, char *mode, int optio
if (wrapper->err_stack) if (wrapper->err_stack)
efree(wrapper->err_stack); efree(wrapper->err_stack);
wrapper->err_stack = NULL; wrapper->err_stack = NULL;
wrapper->err_count = 0;
} }
#if ZEND_DEBUG #if ZEND_DEBUG
if (stream == NULL && copy_of_path != NULL) if (stream == NULL && copy_of_path != NULL)

View file

@ -21,6 +21,7 @@
#include "php.h" #include "php.h"
#include "php_globals.h" #include "php_globals.h"
#include "ext/standard/file.h"
static int le_protocols; static int le_protocols;
@ -137,6 +138,13 @@ static php_stream *user_wrapper_opener(php_stream_wrapper *wrapper, char *filena
int call_result; int call_result;
php_stream *stream = NULL; 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 = emalloc(sizeof(*us));
us->wrapper = uwrap; 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(&zmode);
zval_ptr_dtor(&zfilename); zval_ptr_dtor(&zfilename);
FG(user_stream_current_filename) = NULL;
return stream; return stream;
} }