summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ext/standard/file.c1
-rw-r--r--ext/standard/file.h1
-rwxr-xr-xmain/streams.c3
-rw-r--r--main/user_streams.c10
4 files changed, 14 insertions, 1 deletions
diff --git a/ext/standard/file.c b/ext/standard/file.c
index b3d2fb539f..38497a4a71 100644
--- a/ext/standard/file.c
+++ b/ext/standard/file.c
@@ -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;
}
diff --git a/ext/standard/file.h b/ext/standard/file.h
index 3990504509..4e5eba55dd 100644
--- a/ext/standard/file.h
+++ b/ext/standard/file.h
@@ -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
diff --git a/main/streams.c b/main/streams.c
index fd22218901..ba8176dd63 100755
--- a/main/streams.c
+++ b/main/streams.c
@@ -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)
diff --git a/main/user_streams.c b/main/user_streams.c
index a6aff3cb8a..5c4ef63b92 100644
--- a/main/user_streams.c
+++ b/main/user_streams.c
@@ -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;
}