mirror of
https://github.com/php/php-src.git
synced 2025-08-18 15:08:55 +02:00
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:
parent
1f227cd2e3
commit
c484eb8c97
4 changed files with 14 additions and 1 deletions
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue