summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ext/standard/http_fopen_wrapper.c30
1 files changed, 26 insertions, 4 deletions
diff --git a/ext/standard/http_fopen_wrapper.c b/ext/standard/http_fopen_wrapper.c
index f3d9c95aa7..c6e04c1dfd 100644
--- a/ext/standard/http_fopen_wrapper.c
+++ b/ext/standard/http_fopen_wrapper.c
@@ -80,8 +80,10 @@
#include "php_fopen_wrappers.h"
#define HTTP_HEADER_BLOCK_SIZE 1024
+#define PHP_URL_REDIRECT_MAX 20
-php_stream *php_stream_url_wrap_http(php_stream_wrapper *wrapper, char *path, char *mode, int options, char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC)
+
+php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper, char *path, char *mode, int options, char **opened_path, php_stream_context *context, int redirect_max STREAMS_DC TSRMLS_DC)
{
php_stream *stream = NULL;
php_url *resource = NULL;
@@ -102,14 +104,25 @@ php_stream *php_stream_url_wrap_http(php_stream_wrapper *wrapper, char *path, ch
char *transport_string, *errstr = NULL;
int transport_len;
+ if (redirect_max < 1) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Circular redirect, aborting.");
+ return NULL;
+ }
+
if (strpbrk(mode, "awx+")) {
php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "HTTP wrapper does not support writeable connections.");
return NULL;
}
resource = php_url_parse(path);
- if (resource == NULL)
+ if (resource == NULL) {
return NULL;
+ }
+
+ if (strncasecmp(resource->scheme, "http", sizeof("http")) && strncasecmp(resource->scheme, "https", sizeof("https"))) {
+ php_url_free(resource);
+ return php_stream_open_wrapper_ex(path, mode, ENFORCE_SAFE_MODE | REPORT_ERRORS, NULL, context);
+ }
use_ssl = resource->scheme && (strlen(resource->scheme) > 4) && resource->scheme[4] == 's';
/* choose default ports */
@@ -349,7 +362,11 @@ php_stream *php_stream_url_wrap_http(php_stream_wrapper *wrapper, char *path, ch
char loc_path[HTTP_HEADER_BLOCK_SIZE];
*new_path='\0';
- if (strlen(location)<8 || (strncasecmp(location, "http://", sizeof("http://")-1) && strncasecmp(location, "https://", sizeof("https://")-1))) {
+ if (strlen(location)<8 || (strncasecmp(location, "http://", sizeof("http://")-1) &&
+ strncasecmp(location, "https://", sizeof("https://")-1) &&
+ strncasecmp(location, "ftp://", sizeof("ftp://")-1) &&
+ strncasecmp(location, "ftps://", sizeof("ftps://")-1)))
+ {
if (*location != '/') {
if (*(location+1) != '\0' && resource->path) {
char *s = strrchr(resource->path, '/');
@@ -377,7 +394,7 @@ php_stream *php_stream_url_wrap_http(php_stream_wrapper *wrapper, char *path, ch
} else {
strlcpy(new_path, location, sizeof(new_path));
}
- stream = php_stream_url_wrap_http(NULL, new_path, mode, options, opened_path, context STREAMS_CC TSRMLS_CC);
+ stream = php_stream_url_wrap_http_ex(NULL, new_path, mode, options, opened_path, context, --redirect_max STREAMS_CC TSRMLS_CC);
if (stream && stream->wrapperdata) {
entryp = &entry;
MAKE_STD_ZVAL(entry);
@@ -435,6 +452,11 @@ out:
return stream;
}
+php_stream *php_stream_url_wrap_http(php_stream_wrapper *wrapper, char *path, char *mode, int options, char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC)
+{
+ return php_stream_url_wrap_http_ex(wrapper, path, mode, options, opened_path, context, PHP_URL_REDIRECT_MAX STREAMS_CC TSRMLS_CC);
+}
+
static int php_stream_http_stream_stat(php_stream_wrapper *wrapper,
php_stream *stream,
php_stream_statbuf *ssb