summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Zend/zend_exceptions.c3
-rw-r--r--ext/curl/interface.c4
-rw-r--r--ext/curl/tests/bug69316.phpt41
-rw-r--r--ext/dom/document.c5
-rw-r--r--ext/dom/tests/DOMDocument_loadHTMLfile_error2.phpt5
-rw-r--r--ext/fileinfo/fileinfo.c5
-rw-r--r--ext/fileinfo/libmagic/softmagic.c3
-rw-r--r--ext/fileinfo/tests/bug68819_001.phpt18
-rw-r--r--ext/fileinfo/tests/bug68819_002.phpt26
-rw-r--r--ext/fileinfo/tests/finfo_file_basic.phpt4
-rw-r--r--ext/gd/gd.c8
-rw-r--r--ext/gd/tests/imageloadfont_error1.phpt6
-rw-r--r--ext/hash/hash.c7
-rw-r--r--ext/hash/tests/hash_hmac_file_error.phpt7
-rw-r--r--ext/pgsql/pgsql.c2
-rw-r--r--ext/phar/phar.c78
-rw-r--r--ext/phar/phar_internal.h11
-rw-r--r--ext/phar/tests/bug69324.pharbin0 -> 269 bytes
-rw-r--r--ext/phar/tests/bug69324.phpt17
-rw-r--r--ext/phar/tests/bug69441.pharbin0 -> 5780 bytes
-rw-r--r--ext/phar/tests/bug69441.phpt21
-rw-r--r--ext/standard/http_fopen_wrapper.c88
-rw-r--r--ext/standard/link.c2
-rw-r--r--ext/standard/streamsfuncs.c2
-rw-r--r--ext/standard/tests/file/readlink_variation1.phpt2
-rw-r--r--ext/standard/tests/http/bug69337.phpt41
-rw-r--r--ext/standard/tests/serialize/bug69152.phpt16
-rw-r--r--ext/xmlwriter/php_xmlwriter.c4
-rw-r--r--ext/zlib/tests/gzopen_variation1.phpt28
-rw-r--r--ext/zlib/tests/readgzfile_variation1.phpt10
-rw-r--r--ext/zlib/tests/readgzfile_variation6.phpt4
-rw-r--r--ext/zlib/zlib.c4
-rw-r--r--sapi/apache2handler/sapi_apache2.c1
33 files changed, 352 insertions, 121 deletions
diff --git a/Zend/zend_exceptions.c b/Zend/zend_exceptions.c
index bf90ae7be3..1ca2eadbf4 100644
--- a/Zend/zend_exceptions.c
+++ b/Zend/zend_exceptions.c
@@ -591,6 +591,9 @@ ZEND_METHOD(exception, getTraceAsString)
str = &res;
trace = zend_read_property(default_exception_ce, getThis(), "trace", sizeof("trace")-1, 1 TSRMLS_CC);
+ if(Z_TYPE_P(trace) != IS_ARRAY) {
+ RETURN_FALSE;
+ }
zend_hash_apply_with_arguments(Z_ARRVAL_P(trace) TSRMLS_CC, (apply_func_args_t)_build_trace_string, 3, str, len, &num);
s_tmp = emalloc(1 + MAX_LENGTH_OF_LONG + 7 + 1);
diff --git a/ext/curl/interface.c b/ext/curl/interface.c
index 0423f71f9a..7f8f276791 100644
--- a/ext/curl/interface.c
+++ b/ext/curl/interface.c
@@ -1051,6 +1051,7 @@ static size_t curl_write(char *data, size_t size, size_t nmemb, void *ctx)
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not call the CURLOPT_WRITEFUNCTION");
length = -1;
} else if (retval_ptr) {
+ _php_curl_verify_handlers(ch, 1 TSRMLS_CC);
if (Z_TYPE_P(retval_ptr) != IS_LONG) {
convert_to_long_ex(&retval_ptr);
}
@@ -1124,6 +1125,7 @@ static size_t curl_progress(void *clientp, double dltotal, double dlnow, double
if (error == FAILURE) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot call the CURLOPT_PROGRESSFUNCTION");
} else if (retval_ptr) {
+ _php_curl_verify_handlers(ch, 1 TSRMLS_CC);
if (Z_TYPE_P(retval_ptr) != IS_LONG) {
convert_to_long_ex(&retval_ptr);
}
@@ -1200,6 +1202,7 @@ static size_t curl_read(char *data, size_t size, size_t nmemb, void *ctx)
length = CURL_READFUNC_ABORT;
#endif
} else if (retval_ptr) {
+ _php_curl_verify_handlers(ch, 1 TSRMLS_CC);
if (Z_TYPE_P(retval_ptr) == IS_STRING) {
length = MIN((int) (size * nmemb), Z_STRLEN_P(retval_ptr));
memcpy(data, Z_STRVAL_P(retval_ptr), length);
@@ -1274,6 +1277,7 @@ static size_t curl_write_header(char *data, size_t size, size_t nmemb, void *ctx
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not call the CURLOPT_HEADERFUNCTION");
length = -1;
} else if (retval_ptr) {
+ _php_curl_verify_handlers(ch, 1 TSRMLS_CC);
if (Z_TYPE_P(retval_ptr) != IS_LONG) {
convert_to_long_ex(&retval_ptr);
}
diff --git a/ext/curl/tests/bug69316.phpt b/ext/curl/tests/bug69316.phpt
new file mode 100644
index 0000000000..2a88eb2bc9
--- /dev/null
+++ b/ext/curl/tests/bug69316.phpt
@@ -0,0 +1,41 @@
+--TEST--
+Bug #69316: Use-after-free in php_curl related to CURLOPT_FILE/_INFILE/_WRITEHEADER
+--SKIPIF--
+<?php
+if (!extension_loaded("curl")) exit("skip curl extension not loaded");
+if (false === getenv('PHP_CURL_HTTP_REMOTE_SERVER')) exit("skip PHP_CURL_HTTP_REMOTE_SERVER env variable is not defined");
+?>
+--FILE--
+<?php
+ function hdr_callback($ch, $data) {
+ // close the stream, causing the FILE structure to be free()'d
+ if($GLOBALS['f_file']) {
+ fclose($GLOBALS['f_file']); $GLOBALS['f_file'] = 0;
+
+ // cause an allocation of approx the same size as a FILE structure, size varies a bit depending on platform/libc
+ $FILE_size = (PHP_INT_SIZE == 4 ? 0x160 : 0x238);
+ curl_setopt($ch, CURLOPT_COOKIE, str_repeat("a", $FILE_size - 1));
+ }
+ return strlen($data);
+ }
+ $host = getenv('PHP_CURL_HTTP_REMOTE_SERVER');
+
+ $temp_file = dirname(__FILE__) . '/body.tmp';
+ $url = "{$host}/get.php?test=getpost";
+ $ch = curl_init();
+ $f_file = fopen($temp_file, "w") or die("failed to open file\n");
+ curl_setopt($ch, CURLOPT_BUFFERSIZE, 10);
+ curl_setopt($ch, CURLOPT_HEADERFUNCTION, "hdr_callback");
+ curl_setopt($ch, CURLOPT_FILE, $f_file);
+ curl_setopt($ch, CURLOPT_URL, $url);
+ curl_exec($ch);
+ curl_close($ch);
+?>
+===DONE===
+--CLEAN--
+<?php
+unlink(dirname(__FILE__) . '/body.tmp');
+?>
+--EXPECTF--
+Warning: curl_exec(): CURLOPT_FILE resource has gone away, resetting to default in %s on line %d
+===DONE===
diff --git a/ext/dom/document.c b/ext/dom/document.c
index f105f6d7fe..4666746ad2 100644
--- a/ext/dom/document.c
+++ b/ext/dom/document.c
@@ -1580,6 +1580,9 @@ static xmlDocPtr dom_document_parser(zval *id, int mode, char *source, int sourc
xmlInitParser();
if (mode == DOM_LOAD_FILE) {
+ if (CHECK_NULL_PATH(source, source_len)) {
+ return NULL;
+ }
char *file_dest = _dom_get_valid_file_path(source, resolved_path, MAXPATHLEN TSRMLS_CC);
if (file_dest) {
ctxt = xmlCreateFileParserCtxt(file_dest);
@@ -2168,7 +2171,7 @@ static void dom_load_html(INTERNAL_FUNCTION_PARAMETERS, int mode) /* {{{ */
id = getThis();
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &source, &source_len, &options) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p|l", &source, &source_len, &options) == FAILURE) {
return;
}
diff --git a/ext/dom/tests/DOMDocument_loadHTMLfile_error2.phpt b/ext/dom/tests/DOMDocument_loadHTMLfile_error2.phpt
index e59ff56c5a..75004e2a74 100644
--- a/ext/dom/tests/DOMDocument_loadHTMLfile_error2.phpt
+++ b/ext/dom/tests/DOMDocument_loadHTMLfile_error2.phpt
@@ -13,6 +13,11 @@ assert.bail=true
$doc = new DOMDocument();
$result = $doc->loadHTMLFile("");
assert('$result === false');
+$doc = new DOMDocument();
+$result = $doc->loadHTMLFile("text.html\0something");
+assert('$result === null');
?>
--EXPECTF--
%r(PHP ){0,1}%rWarning: DOMDocument::loadHTMLFile(): Empty string supplied as input %s
+
+%r(PHP ){0,1}%rWarning: DOMDocument::loadHTMLFile() expects parameter 1 to be a valid path, string given %s
diff --git a/ext/fileinfo/fileinfo.c b/ext/fileinfo/fileinfo.c
index 2d523ab498..5fd9511745 100644
--- a/ext/fileinfo/fileinfo.c
+++ b/ext/fileinfo/fileinfo.c
@@ -506,6 +506,11 @@ static void _php_finfo_get_type(INTERNAL_FUNCTION_PARAMETERS, int mode, int mime
RETVAL_FALSE;
goto clean;
}
+ if (CHECK_NULL_PATH(buffer, buffer_len)) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid path");
+ RETVAL_FALSE;
+ goto clean;
+ }
wrap = php_stream_locate_url_wrapper(buffer, &tmp2, 0 TSRMLS_CC);
diff --git a/ext/fileinfo/libmagic/softmagic.c b/ext/fileinfo/libmagic/softmagic.c
index e7b7855eef..54c1a03ef7 100644
--- a/ext/fileinfo/libmagic/softmagic.c
+++ b/ext/fileinfo/libmagic/softmagic.c
@@ -1037,6 +1037,9 @@ mcopy(struct magic_set *ms, union VALUETYPE *p, int type, int indir,
if (bytecnt > nbytes) {
bytecnt = nbytes;
}
+ if (offset > bytecnt) {
+ offset = bytecnt;
+ }
if (s == NULL) {
ms->search.s_len = 0;
ms->search.s = NULL;
diff --git a/ext/fileinfo/tests/bug68819_001.phpt b/ext/fileinfo/tests/bug68819_001.phpt
new file mode 100644
index 0000000000..ce39ee61db
--- /dev/null
+++ b/ext/fileinfo/tests/bug68819_001.phpt
@@ -0,0 +1,18 @@
+--TEST--
+Bug #68819 Fileinfo on specific file causes spurious OOM and/or segfault, var 1
+--SKIPIF--
+<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?>
+--FILE--
+<?php
+
+$string = <<<HERE
+----a-----'''---------a---------------a--------a-----a-----a---------a-----as-------a----a--a-------------a--as-----s---------------a---------a---a--s-a-----a-----------asy---------a-----a-----------a----s--------a-------------a-------a--------a----s------------a-----a----------------a----s-----------------\r\n-------------------a-------a-a-------a-----a----a----s----s--------a-----------------------a----a----s-------------a------------------s-------a----a---a------as---s-a--------------s-----a------a-y--a-------a-----a--a--------a----s--------a-------------a-------a--------a----s--------------a-----a----------a----------s--a----------s-----------------\r\n-------------------a-------a-a-------a-----a----a----s----s--------a----------a----------------------a----a----s-------------a----------------------------s-------a----a---a------as---s-a--------------s-----a------a-y--a-------a-----a--a--------a----s--------a-------------a-------a--------a----s--------------a-----a----------a----------s--a----------s-----------------\r\n------a-------a-a-------a-----a----a---a-----a-----------------------a----a---a-----a------------------s-------a----a---a-----a------as---s-a--------------s-----a------a-y--a-------a-----a--a--------a----s--------a-------------a-------a--------a----s--------------a-----a----------a----------s--a----------s------\r\n-------------------a-------a-a-------a-----a----a---a-------a------------------------a----a---a-----''--a-------------------s-------a----a---a------as---s-a--------------s-----a------a-y--a-------a-----a--a--------a----s--------a-------------a-------a--------a----s--------------a-----a----------a----------s--a----------s-----------------\r\n-------------------a-------a-a-------a-----a----a-------s-----a---a-------------------------a----a-------------a---a-------------------s-------a----a-------------a---a-----as-a--------------a-----a--s----s---------y------------a-----a-s---a-------''----a---s--a-''------''----s------------a-y----------------s------a-----y--a-s--a-s------s--a-s----------''----------------------------a---s--a----a---------a-s---a-s--------s--------a---------s--a-y-------------as----a----a-------------a------a---s--a-s------a--------a----s----y--as--a----a-s---------------a-----a--------------------------------------\r\n-------------------a-------a-a-------a-----a----a-----------s--------a-----------------------a----a--------------------a------------------s-------a----a---a------as---s-a--------------s-----a------a-y--a-------a-----a--a--------a----s--------a-------------a-------a--------a----s--------------a-----a----------a----------s--a----------s-----------------\r\n-------------------a-------a-a-------a-----a----a-----------s--------a----------a----------------------a----a--------------------a------------------------------s-------a----a---a------as---s-a--------------s-----a------a-y--a-------a-----a--a--------a----s--------a-------------a-------a--------a----s--------------a-----a----------a----------s--a----------s-----------------\r\n-------------------a-------a-a-------a-----a----a---a-----------------------a----a---a------------------s-------a----a---a------as---s-a--------------s-----a------a-y--a-------a-----a--a--------a----s--------a-------------a-------a--------a----s--------------a-----a----------a----------s--a----------s-----------------\r\n-------------------a-------a-a-------a-----a----a---a----------a----------------------a----a---a------------------------------s-------a----a---a------as---s-a--------------s-----a------a-y--a-------a-----a--a--------a----s--------a-------------a-------a--------a----s--------------a-----a----------a----------s--a----------s-----------------\r\n-----a-a-----------a-------a-a-------a-----a----a----a---s-----a-----------------------a----a----a---------a-----------------s-------a----a----a---------a------as---s-a--------------s-----a------a-y--a-------a-----a--a--------a----s--------a-------------a-------a--------a----s--------------a-----a----------a----------s--a----------s-----------------\r\n-------------------a-------a-a-------a-----a----a--------a----a-----------------------a----a----------a----a------------------s-------a----a---a------as---s-a--------------s-----a------a-y--a-------a-----a--a--------a----s--------a-------------a-------a--------a----s--------------a-----a----------a----------s--a----------s-----------------\r\n-----a-------------a-------a-a-------a-----a----a--------s-----a---a-------------------------a----a--------------a---a-------------------s-------------a---------------a----a---a---a-----as-a--------------a-----a--s----s---------y------------a-----a-s---a-------''----a---s--a-''------''----s------------a-y----------------s------a-----y--a-s--a-s------s--a-s----------''----------------------------a---s--a----a---------a-s---a-s--------s--------a---------s--a-y-------------as----a----a-------------a------a---s--a-s------a--------a----s----y--as--a----a-s---------------a-----a--------------------------------------\r\n-------------------a-------a-a-------a-----a----a----------------a-----------------------a----a----------------a------------------s-------a----a---a------as---s-a--------------s-----a------a-y--a-------a-----a--a--------a----s--------a-------------a-------a--------a----s--------------a-----a----------a----------s--a----------s-----------------\r\n-------------------a-------a-a-------a-----a----a----------------a----------a----------------------a----a----------------a-----------------------------s-------a----a---a------as---s-a--------------s-----a------a-y--a-------a-----a--a--------a----s--------a-------------a-------a--------a----s--------------a-----a----------a----------s--a----------s-----------------\r\n---a---------------a-------a-a-------a-----as------------------------a--a--s------------------a-s------------------------a-----s--a-----'''----------a-s---------------------------------------------a-----s--a-----------------a---------a---a--s-a-----a-----------asy---------a-----a-----------a----s----------------------a----s--a-------------a-------a--------a----s------------a-----a----------------a----s------------------\r\n-a-----------------a-------a-a-------a--y---------a------------------y---------a-----'''-------y------a-y--a-------------------------a---------a---a----------as-a---a--s-a-----a-----------asy---------a-----a-----------a----s--------a-------------a-------a--------a----s---------a-----a----------------a----s------------------\r\n-a-----------------a-------a-a-------a--y-------------a------------------y-------------a-----'''-------y----------a-y--a-------------------------a---------a---a----------as-a---a--s-a-----a-----------asy---------a-----a-----------a----s--------a-------------a-------a--------a----s---------a-----a----------------a----s------------------\r\n-------------------a-------a-a-------a--a----a-----a------------------a----a-----a-----'''----------a----s----a----a-------s---a------------------a-----------a--s-a-----a---------------------a------a----s-a-----a-------s-s-------a----s--------a-------------a-------a--------a----s---------a-----a----------------a----s------------------\r\n------aa-----------a-------a-a------------s-a--s---------a---a------------------------a------------a---a------------------s--------a------------a---a------as---s-a--------------s-----a------a-y--a-------a-----a--a--------a----s--------a-------------a-------a--------a----s--------------a-----a----------a----------s--a----------s-----------------\r\n-------------------a-------a-a------------------------s-----s--a----a-----------------------------------------s--a----a------------------s---------------------------------s--a----a------as---s-a--------------s-----a------a-y--a-------a-----a--a--------a----s--------a-------------a-------a--------a----s--------------a-----a----------a----------s--a----------s-----------------\r\n-------------------a-------a-a--------------s-a---a--------------------------a---a------------------s----------a---a------as---s-a--------------s-----a------a-y--a-------a-----a--a--------a----s--------a-------------a-------a--------a----s---------------a-----a----------a----------s--a----------s-----------------\r\nsay-------a------------s-----''------a----s--------a-------------a-\r\n
+HERE;
+
+$finfo = new finfo();
+$type = $finfo->buffer($string);
+
+var_dump($type);
+?>
+--EXPECT--
+string(60) "ASCII text, with very long lines, with CRLF line terminators"
diff --git a/ext/fileinfo/tests/bug68819_002.phpt b/ext/fileinfo/tests/bug68819_002.phpt
new file mode 100644
index 0000000000..cec238d63e
--- /dev/null
+++ b/ext/fileinfo/tests/bug68819_002.phpt
@@ -0,0 +1,26 @@
+--TEST--
+Bug #68819 Fileinfo on specific file causes spurious OOM and/or segfault, var 2
+--SKIPIF--
+<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?>
+--FILE--
+<?php
+
+$string = '';
+
+// These two in any order
+$string .= "\r\n";
+$string .= "''''";
+
+// Total string length > 8192
+$string .= str_repeat(chr(rand(32, 127)), 8184);
+
+// Ending in this string
+$string .= "say";
+
+$finfo = new finfo();
+$type = $finfo->buffer($string);
+var_dump($type);
+
+?>
+--EXPECT--
+string(60) "ASCII text, with very long lines, with CRLF line terminators"
diff --git a/ext/fileinfo/tests/finfo_file_basic.phpt b/ext/fileinfo/tests/finfo_file_basic.phpt
index 20223fd88e..ee70e2e253 100644
--- a/ext/fileinfo/tests/finfo_file_basic.phpt
+++ b/ext/fileinfo/tests/finfo_file_basic.phpt
@@ -19,6 +19,7 @@ echo "*** Testing finfo_file() : basic functionality ***\n";
var_dump( finfo_file( $finfo, __FILE__) );
var_dump( finfo_file( $finfo, __FILE__, FILEINFO_CONTINUE ) );
var_dump( finfo_file( $finfo, $magicFile ) );
+var_dump( finfo_file( $finfo, $magicFile.chr(0).$magicFile) );
?>
===DONE===
@@ -27,4 +28,7 @@ var_dump( finfo_file( $finfo, $magicFile ) );
string(28) "text/x-php; charset=us-ascii"
string(22) "PHP script, ASCII text"
string(25) "text/plain; charset=utf-8"
+
+Warning: finfo_file(): Invalid path in %s/finfo_file_basic.php on line %d
+bool(false)
===DONE===
diff --git a/ext/gd/gd.c b/ext/gd/gd.c
index e5657f7424..d258c3dbc7 100644
--- a/ext/gd/gd.c
+++ b/ext/gd/gd.c
@@ -1495,7 +1495,7 @@ PHP_FUNCTION(imageloadfont)
gdFontPtr font;
php_stream *stream;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &file, &file_name) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p", &file, &file_name) == FAILURE) {
return;
}
@@ -2438,7 +2438,7 @@ static void _php_image_create_from(INTERNAL_FUNCTION_PARAMETERS, int image_type,
long ignore_warning;
#endif
if (image_type == PHP_GDIMG_TYPE_GD2PART) {
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sllll", &file, &file_len, &srcx, &srcy, &width, &height) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "pllll", &file, &file_len, &srcx, &srcy, &width, &height) == FAILURE) {
return;
}
if (width < 1 || height < 1) {
@@ -2446,7 +2446,7 @@ static void _php_image_create_from(INTERNAL_FUNCTION_PARAMETERS, int image_type,
RETURN_FALSE;
}
} else {
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &file, &file_len) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p", &file, &file_len) == FAILURE) {
return;
}
}
@@ -4178,7 +4178,7 @@ PHP_FUNCTION(imagepsencodefont)
char *enc, **enc_vector;
int enc_len, *f_ind;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &fnt, &enc, &enc_len) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rp", &fnt, &enc, &enc_len) == FAILURE) {
return;
}
diff --git a/ext/gd/tests/imageloadfont_error1.phpt b/ext/gd/tests/imageloadfont_error1.phpt
index 16d1a3c3a6..418bbf3ced 100644
--- a/ext/gd/tests/imageloadfont_error1.phpt
+++ b/ext/gd/tests/imageloadfont_error1.phpt
@@ -3,7 +3,7 @@ Testing that imageloadfont() breaks on non-string first parameter
--CREDITS--
Neveo Harrison <neveoo [at] gmail [dot] com> #testfest #tek11
--SKIPIF--
-<?php
+<?php
if (!extension_loaded("gd")) die("skip GD not present");
?>
--FILE--
@@ -11,5 +11,5 @@ Neveo Harrison <neveoo [at] gmail [dot] com> #testfest #tek11
var_dump( imageloadfont(array()) );
?>
--EXPECTF--
-Warning: imageloadfont() expects parameter 1 to be string, array given in %s on line %d
-NULL \ No newline at end of file
+Warning: imageloadfont() expects parameter 1 to be a valid path, array given in %s on line %d
+NULL
diff --git a/ext/hash/hash.c b/ext/hash/hash.c
index bd9dcca59f..f5988c9c66 100644
--- a/ext/hash/hash.c
+++ b/ext/hash/hash.c
@@ -142,6 +142,7 @@ static void php_hash_do_hash(INTERNAL_FUNCTION_PARAMETERS, int isfilename, zend_
}
if (isfilename) {
if (CHECK_NULL_PATH(data, data_len)) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid path");
RETURN_FALSE;
}
stream = php_stream_open_wrapper_ex(data, "rb", REPORT_ERRORS, NULL, DEFAULT_CONTEXT);
@@ -222,6 +223,10 @@ static void php_hash_do_hash_hmac(INTERNAL_FUNCTION_PARAMETERS, int isfilename,
RETURN_FALSE;
}
if (isfilename) {
+ if (CHECK_NULL_PATH(data, data_len)) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid path");
+ RETURN_FALSE;
+ }
stream = php_stream_open_wrapper_ex(data, "rb", REPORT_ERRORS, NULL, DEFAULT_CONTEXT);
if (!stream) {
/* Stream will report errors opening file */
@@ -449,7 +454,7 @@ PHP_FUNCTION(hash_update_file)
char *filename, buf[1024];
int filename_len, n;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs|r", &zhash, &filename, &filename_len, &zcontext) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rp|r", &zhash, &filename, &filename_len, &zcontext) == FAILURE) {
return;
}
diff --git a/ext/hash/tests/hash_hmac_file_error.phpt b/ext/hash/tests/hash_hmac_file_error.phpt
index 42ab122285..26ba8aacbe 100644
--- a/ext/hash/tests/hash_hmac_file_error.phpt
+++ b/ext/hash/tests/hash_hmac_file_error.phpt
@@ -28,6 +28,9 @@ hash_hmac_file('crc32', $file, $key, TRUE, $extra_arg);
echo "\n-- Testing hash_hmac_file() function with invalid hash algorithm --\n";
hash_hmac_file('foo', $file, $key, TRUE);
+echo "\n-- Testing hash_hmac_file() function with bad path --\n";
+hash_hmac_file('crc32', $file.chr(0).$file, $key, TRUE);
+
?>
===Done===
--EXPECTF--
@@ -51,4 +54,8 @@ Warning: hash_hmac_file() expects at most 4 parameters, 5 given in %s on line %d
-- Testing hash_hmac_file() function with invalid hash algorithm --
Warning: hash_hmac_file(): Unknown hashing algorithm: foo in %s on line %d
+
+-- Testing hash_hmac_file() function with bad path --
+
+Warning: hash_hmac_file(): Invalid path in %s on line %d
===Done=== \ No newline at end of file
diff --git a/ext/pgsql/pgsql.c b/ext/pgsql/pgsql.c
index eb55777758..cd51143c90 100644
--- a/ext/pgsql/pgsql.c
+++ b/ext/pgsql/pgsql.c
@@ -3014,7 +3014,7 @@ PHP_FUNCTION(pg_trace)
php_stream *stream;
id = PGG(default_link);
- if (zend_parse_parameters(argc TSRMLS_CC, "s|sr", &z_filename, &z_filename_len, &mode, &mode_len, &pgsql_link) == FAILURE) {
+ if (zend_parse_parameters(argc TSRMLS_CC, "p|sr", &z_filename, &z_filename_len, &mode, &mode_len, &pgsql_link) == FAILURE) {
return;
}
diff --git a/ext/phar/phar.c b/ext/phar/phar.c
index ec82351410..c5c8b467bc 100644
--- a/ext/phar/phar.c
+++ b/ext/phar/phar.c
@@ -600,52 +600,41 @@ int phar_open_parsed_phar(char *fname, int fname_len, char *alias, int alias_len
*
* Meta-data is in this format:
* [len32][data...]
- *
+ *
* data is the serialized zval
*/
-int phar_parse_metadata(char **buffer, zval **metadata, int zip_metadata_len TSRMLS_DC) /* {{{ */
+int phar_parse_metadata(char **buffer, zval **metadata, php_uint32 zip_metadata_len TSRMLS_DC) /* {{{ */
{
- const unsigned char *p;
- php_uint32 buf_len;
php_unserialize_data_t var_hash;
- if (!zip_metadata_len) {
- PHAR_GET_32(*buffer, buf_len);
- } else {
- buf_len = zip_metadata_len;
- }
-
- if (buf_len) {
+ if (zip_metadata_len) {
+ const unsigned char *p, *p_buff = estrndup(*buffer, zip_metadata_len);
+ p = p_buff;
ALLOC_ZVAL(*metadata);
INIT_ZVAL(**metadata);
- p = (const unsigned char*) *buffer;
PHP_VAR_UNSERIALIZE_INIT(var_hash);
- if (!php_var_unserialize(metadata, &p, p + buf_len, &var_hash TSRMLS_CC)) {
+ if (!php_var_unserialize(metadata, &p, p + zip_metadata_len, &var_hash TSRMLS_CC)) {
+ efree(p_buff);
PHP_VAR_UNSERIALIZE_DESTROY(var_hash);
zval_ptr_dtor(metadata);
*metadata = NULL;
return FAILURE;
}
-
+ efree(p_buff);
PHP_VAR_UNSERIALIZE_DESTROY(var_hash);
if (PHAR_G(persist)) {
/* lazy init metadata */
zval_ptr_dtor(metadata);
- *metadata = (zval *) pemalloc(buf_len, 1);
- memcpy(*metadata, *buffer, buf_len);
- *buffer += buf_len;
+ *metadata = (zval *) pemalloc(zip_metadata_len, 1);
+ memcpy(*metadata, *buffer, zip_metadata_len);
return SUCCESS;
}
} else {
*metadata = NULL;
}
- if (!zip_metadata_len) {
- *buffer += buf_len;
- }
-
return SUCCESS;
}
/* }}}*/
@@ -655,7 +644,7 @@ int phar_parse_metadata(char **buffer, zval **metadata, int zip_metadata_len TSR
*
* Parse a new one and add it to the cache, returning either SUCCESS or
* FAILURE, and setting pphar to the pointer to the manifest entry
- *
+ *
* This is used by phar_open_from_filename to process the manifest, but can be called
* directly.
*/
@@ -666,6 +655,7 @@ static int phar_parse_pharfile(php_stream *fp, char *fname, int fname_len, char
phar_entry_info entry;
php_uint32 manifest_len, manifest_count, manifest_flags, manifest_index, tmp_len, sig_flags;
php_uint16 manifest_ver;
+ php_uint32 len;
long offset;
int sig_len, register_alias = 0, temp_alias = 0;
char *signature = NULL;
@@ -1031,16 +1021,21 @@ static int phar_parse_pharfile(php_stream *fp, char *fname, int fname_len, char
mydata->is_persistent = PHAR_G(persist);
/* check whether we have meta data, zero check works regardless of byte order */
+ PHAR_GET_32(buffer, len);
if (mydata->is_persistent) {
- PHAR_GET_32(buffer, mydata->metadata_len);
- if (phar_parse_metadata(&buffer, &mydata->metadata, mydata->metadata_len TSRMLS_CC) == FAILURE) {
- MAPPHAR_FAIL("unable to read phar metadata in .phar file \"%s\"");
- }
- } else {
- if (phar_parse_metadata(&buffer, &mydata->metadata, 0 TSRMLS_CC) == FAILURE) {
- MAPPHAR_FAIL("unable to read phar metadata in .phar file \"%s\"");
+ mydata->metadata_len = len;
+ if(!len) {
+ /* FIXME: not sure why this is needed but removing it breaks tests */
+ PHAR_GET_32(buffer, len);
}
}
+ if(len > endbuffer - buffer) {
+ MAPPHAR_FAIL("internal corruption of phar \"%s\" (trying to read past buffer end)");
+ }
+ if (phar_parse_metadata(&buffer, &mydata->metadata, len TSRMLS_CC) == FAILURE) {
+ MAPPHAR_FAIL("unable to read phar metadata in .phar file \"%s\"");
+ }
+ buffer += len;
/* set up our manifest */
zend_hash_init(&mydata->manifest, manifest_count,
@@ -1075,7 +1070,7 @@ static int phar_parse_pharfile(php_stream *fp, char *fname, int fname_len, char
entry.manifest_pos = manifest_index;
}
- if (buffer + entry.filename_len + 20 > endbuffer) {
+ if (entry.filename_len + 20 > endbuffer - buffer) {
MAPPHAR_FAIL("internal corruption of phar \"%s\" (truncated manifest entry)");
}
@@ -1111,19 +1106,20 @@ static int phar_parse_pharfile(php_stream *fp, char *fname, int fname_len, char
entry.flags |= PHAR_ENT_PERM_DEF_DIR;
}
+ PHAR_GET_32(buffer, len);
if (entry.is_persistent) {
- PHAR_GET_32(buffer, entry.metadata_len);
- if (!entry.metadata_len) buffer -= 4;
- if (phar_parse_metadata(&buffer, &entry.metadata, entry.metadata_len TSRMLS_CC) == FAILURE) {
- pefree(entry.filename, entry.is_persistent);
- MAPPHAR_FAIL("unable to read file metadata in .phar file \"%s\"");
- }
+ entry.metadata_len = len;
} else {
- if (phar_parse_metadata(&buffer, &entry.metadata, 0 TSRMLS_CC) == FAILURE) {
- pefree(entry.filename, entry.is_persistent);
- MAPPHAR_FAIL("unable to read file metadata in .phar file \"%s\"");
- }
+ entry.metadata_len = 0;
}
+ if (len > endbuffer - buffer) {
+ MAPPHAR_FAIL("internal corruption of phar \"%s\" (truncated manifest entry)");
+ }
+ if (phar_parse_metadata(&buffer, &entry.metadata, len TSRMLS_CC) == FAILURE) {
+ pefree(entry.filename, entry.is_persistent);
+ MAPPHAR_FAIL("unable to read file metadata in .phar file \"%s\"");
+ }
+ buffer += len;
entry.offset = entry.offset_abs = offset;
offset += entry.compressed_filesize;
@@ -2241,7 +2237,7 @@ last_time:
/**
* Process a phar stream name, ensuring we can handle any of:
- *
+ *
* - whatever.phar
* - whatever.phar.gz
* - whatever.phar.bz2
diff --git a/ext/phar/phar_internal.h b/ext/phar/phar_internal.h
index c9306c15f4..84282d2a8f 100644
--- a/ext/phar/phar_internal.h
+++ b/ext/phar/phar_internal.h
@@ -618,10 +618,13 @@ static inline void phar_set_inode(phar_entry_info *entry TSRMLS_DC) /* {{{ */
{
char tmp[MAXPATHLEN];
int tmp_len;
+ size_t len;
- tmp_len = entry->filename_len + entry->phar->fname_len;
- memcpy(tmp, entry->phar->fname, entry->phar->fname_len);
- memcpy(tmp + entry->phar->fname_len, entry->filename, entry->filename_len);
+ tmp_len = MIN(MAXPATHLEN, entry->filename_len + entry->phar->fname_len);
+ len = MIN(entry->phar->fname_len, tmp_len);
+ memcpy(tmp, entry->phar->fname, len);
+ len = MIN(tmp_len - len, entry->filename_len);
+ memcpy(tmp + entry->phar->fname_len, entry->filename, len);
entry->inode = (unsigned short)zend_get_hash_value(tmp, tmp_len);
}
/* }}} */
@@ -654,7 +657,7 @@ int phar_mount_entry(phar_archive_data *phar, char *filename, int filename_len,
char *phar_find_in_include_path(char *file, int file_len, phar_archive_data **pphar TSRMLS_DC);
char *phar_fix_filepath(char *path, int *new_len, int use_cwd TSRMLS_DC);
phar_entry_info * phar_open_jit(phar_archive_data *phar, phar_entry_info *entry, char **error TSRMLS_DC);
-int phar_parse_metadata(char **buffer, zval **metadata, int zip_metadata_len TSRMLS_DC);
+int phar_parse_metadata(char **buffer, zval **metadata, php_uint32 zip_metadata_len TSRMLS_DC);
void destroy_phar_manifest_entry(void *pDest);
int phar_seek_efp(phar_entry_info *entry, off_t offset, int whence, off_t position, int follow_links TSRMLS_DC);
php_stream *phar_get_efp(phar_entry_info *entry, int follow_links TSRMLS_DC);
diff --git a/ext/phar/tests/bug69324.phar b/ext/phar/tests/bug69324.phar
new file mode 100644
index 0000000000..0882d88c22
--- /dev/null
+++ b/ext/phar/tests/bug69324.phar
Binary files differ
diff --git a/ext/phar/tests/bug69324.phpt b/ext/phar/tests/bug69324.phpt
new file mode 100644
index 0000000000..70e3f972e7
--- /dev/null
+++ b/ext/phar/tests/bug69324.phpt
@@ -0,0 +1,17 @@
+--TEST--
+Bug #69324: Buffer Over-read in unserialize when parsing Phar
+--SKIPIF--
+<?php
+if (!extension_loaded("phar")) die("skip");
+?>
+--FILE--
+<?php
+try {
+$p = new Phar(dirname(__FILE__).'/bug69324.phar', 0);
+$meta=$p->getMetadata();
+var_dump($meta);
+} catch(Exception $e) {
+ echo $e->getMessage();
+}
+--EXPECTF--
+internal corruption of phar "%s" (truncated manifest entry) \ No newline at end of file
diff --git a/ext/phar/tests/bug69441.phar b/ext/phar/tests/bug69441.phar
new file mode 100644
index 0000000000..80956dce7c
--- /dev/null
+++ b/ext/phar/tests/bug69441.phar
Binary files differ
diff --git a/ext/phar/tests/bug69441.phpt b/ext/phar/tests/bug69441.phpt
new file mode 100644
index 0000000000..ed461cf1f9
--- /dev/null
+++ b/ext/phar/tests/bug69441.phpt
@@ -0,0 +1,21 @@
+--TEST--
+Phar: bug #69441: Buffer Overflow when parsing tar/zip/phar in phar_set_inode
+--SKIPIF--
+<?php if (!extension_loaded("phar")) die("skip"); ?>
+--FILE--
+<?php
+$fname = dirname(__FILE__) . '/bug69441.phar';
+try {
+$r = new Phar($fname, 0);
+} catch(UnexpectedValueException $e) {
+ echo $e;
+}
+?>
+
+==DONE==
+--EXPECTF--
+exception 'UnexpectedValueException' with message 'phar error: corrupted central directory entry, no magic signature in zip-based phar "%s/bug69441.phar"' in %s/bug69441.php:%d
+Stack trace:
+#0 %s/bug69441.php(%d): Phar->__construct('%s', 0)
+#1 {main}
+==DONE== \ No newline at end of file
diff --git a/ext/standard/http_fopen_wrapper.c b/ext/standard/http_fopen_wrapper.c
index 13614ae3b7..bd642875ee 100644
--- a/ext/standard/http_fopen_wrapper.c
+++ b/ext/standard/http_fopen_wrapper.c
@@ -19,7 +19,7 @@
| Sara Golemon <pollita@php.net> |
+----------------------------------------------------------------------+
*/
-/* $Id$ */
+/* $Id$ */
#include "php.h"
#include "php_globals.h"
@@ -152,7 +152,7 @@ php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper, char *path,
}
if (strncasecmp(resource->scheme, "http", sizeof("http")) && strncasecmp(resource->scheme, "https", sizeof("https"))) {
- if (!context ||
+ if (!context ||
php_stream_context_get_option(context, wrapper->wops->label, "proxy", &tmpzval) == FAILURE ||
Z_TYPE_PP(tmpzval) != IS_STRING ||
Z_STRLEN_PP(tmpzval) <= 0) {
@@ -168,7 +168,7 @@ php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper, char *path,
transport_string = estrndup(Z_STRVAL_PP(tmpzval), Z_STRLEN_PP(tmpzval));
} else {
/* Normal http request (possibly with proxy) */
-
+
if (strpbrk(mode, "awx+")) {
php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "HTTP wrapper does not support writeable connections");
php_url_free(resource);
@@ -207,11 +207,11 @@ php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper, char *path,
stream = php_stream_xport_create(transport_string, transport_len, options,
STREAM_XPORT_CLIENT | STREAM_XPORT_CONNECT,
NULL, &timeout, context, &errstr, NULL);
-
+
if (stream) {
php_stream_set_option(stream, PHP_STREAM_OPTION_READ_TIMEOUT, 0, &timeout);
}
-
+
if (errstr) {
php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "%s", errstr);
efree(errstr);
@@ -328,7 +328,7 @@ finish:
/* avoid buffering issues while reading header */
if (options & STREAM_WILL_CAST)
chunk_size = php_stream_set_chunk_size(stream, 1);
-
+
/* avoid problems with auto-detecting when reading the headers -> the headers
* are always in canonical \r\n format */
eol_detect = stream->flags & (PHP_STREAM_FLAG_DETECT_EOL | PHP_STREAM_FLAG_EOL_MAC);
@@ -359,7 +359,7 @@ finish:
}
}
}
-
+
if (context && php_stream_context_get_option(context, "http", "protocol_version", &tmpzval) == SUCCESS) {
SEPARATE_ZVAL(tmpzval);
convert_to_double_ex(tmpzval);
@@ -420,7 +420,7 @@ finish:
if (context && php_stream_context_get_option(context, "http", "header", &tmpzval) == SUCCESS) {
tmp = NULL;
-
+
if (Z_TYPE_PP(tmpzval) == IS_ARRAY) {
HashPosition pos;
zval **tmpheader = NULL;
@@ -460,42 +460,42 @@ finish:
strip_header(user_headers, tmp, "content-type:");
}
- if ((s = strstr(tmp, "user-agent:")) &&
- (s == tmp || *(s-1) == '\r' || *(s-1) == '\n' ||
+ if ((s = strstr(tmp, "user-agent:")) &&
+ (s == tmp || *(s-1) == '\r' || *(s-1) == '\n' ||
*(s-1) == '\t' || *(s-1) == ' ')) {
have_header |= HTTP_HEADER_USER_AGENT;
}
if ((s = strstr(tmp, "host:")) &&
- (s == tmp || *(s-1) == '\r' || *(s-1) == '\n' ||
+ (s == tmp || *(s-1) == '\r' || *(s-1) == '\n' ||
*(s-1) == '\t' || *(s-1) == ' ')) {
have_header |= HTTP_HEADER_HOST;
}
if ((s = strstr(tmp, "from:")) &&
- (s == tmp || *(s-1) == '\r' || *(s-1) == '\n' ||
+ (s == tmp || *(s-1) == '\r' || *(s-1) == '\n' ||
*(s-1) == '\t' || *(s-1) == ' ')) {
have_header |= HTTP_HEADER_FROM;
}
if ((s = strstr(tmp, "authorization:")) &&
- (s == tmp || *(s-1) == '\r' || *(s-1) == '\n' ||
+ (s == tmp || *(s-1) == '\r' || *(s-1) == '\n' ||
*(s-1) == '\t' || *(s-1) == ' ')) {
have_header |= HTTP_HEADER_AUTH;
}
if ((s = strstr(tmp, "content-length:")) &&
- (s == tmp || *(s-1) == '\r' || *(s-1) == '\n' ||
+ (s == tmp || *(s-1) == '\r' || *(s-1) == '\n' ||
*(s-1) == '\t' || *(s-1) == ' ')) {
have_header |= HTTP_HEADER_CONTENT_LENGTH;
}
if ((s = strstr(tmp, "content-type:")) &&
- (s == tmp || *(s-1) == '\r' || *(s-1) == '\n' ||
+ (s == tmp || *(s-1) == '\r' || *(s-1) == '\n' ||
*(s-1) == '\t' || *(s-1) == ' ')) {
have_header |= HTTP_HEADER_TYPE;
}
/* remove Proxy-Authorization header */
if (use_proxy && use_ssl && (s = strstr(tmp, "proxy-authorization:")) &&
- (s == tmp || *(s-1) == '\r' || *(s-1) == '\n' ||
+ (s == tmp || *(s-1) == '\r' || *(s-1) == '\n' ||
*(s-1) == '\t' || *(s-1) == ' ')) {
char *p = s + sizeof("proxy-authorization:") - 1;
-
+
while (s > tmp && (*(s-1) == ' ' || *(s-1) == '\t')) s--;
while (*p != 0 && *p != '\r' && *p != '\n') p++;
while (*p == '\r' || *p == '\n') p++;
@@ -534,7 +534,7 @@ finish:
}
tmp = (char*)php_base64_encode((unsigned char*)scratch, strlen(scratch), NULL);
-
+
if (snprintf(scratch, scratch_len, "Authorization: Basic %s\r\n", tmp) > 0) {
php_stream_write(stream, scratch, strlen(scratch));
php_stream_notify_info(context, PHP_STREAM_NOTIFY_AUTH_REQUIRED, NULL, 0);
@@ -552,7 +552,7 @@ finish:
/* Send Host: header so name-based virtual hosts work */
if ((have_header & HTTP_HEADER_HOST) == 0) {
- if ((use_ssl && resource->port != 443 && resource->port != 0) ||
+ if ((use_ssl && resource->port != 443 && resource->port != 0) ||
(!use_ssl && resource->port != 80 && resource->port != 0)) {
if (snprintf(scratch, scratch_len, "Host: %s:%i\r\n", resource->host, resource->port) > 0)
php_stream_write(stream, scratch, strlen(scratch));
@@ -563,7 +563,7 @@ finish:
}
}
- if (context &&
+ if (context &&
php_stream_context_get_option(context, "http", "user_agent", &ua_zval) == SUCCESS &&
Z_TYPE_PP(ua_zval) == IS_STRING) {
ua_str = Z_STRVAL_PP(ua_zval);
@@ -575,9 +575,9 @@ finish:
#define _UA_HEADER "User-Agent: %s\r\n"
char *ua;
size_t ua_len;
-
+
ua_len = sizeof(_UA_HEADER) + strlen(ua_str);
-
+
/* ensure the header is only sent if user_agent is not blank */
if (ua_len > sizeof(_UA_HEADER)) {
ua = emalloc(ua_len + 1);
@@ -591,7 +591,7 @@ finish:
if (ua) {
efree(ua);
}
- }
+ }
}
if (user_headers) {
@@ -649,8 +649,12 @@ finish:
{
zval **rh;
- zend_hash_find(EG(active_symbol_table), "http_response_header", sizeof("http_response_header"), (void **) &rh);
+ if(zend_hash_find(EG(active_symbol_table), "http_response_header", sizeof("http_response_header"), (void **) &rh) != SUCCESS || Z_TYPE_PP(rh) != IS_ARRAY) {
+ php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "HTTP request failed, http_response_header overwritten");
+ goto out;
+ }
response_header = *rh;
+ Z_ADDREF_P(response_header);
}
if (!php_stream_eof(stream)) {
@@ -706,9 +710,9 @@ finish:
php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "HTTP request failed, unexpected end of socket!");
goto out;
}
-
+
/* read past HTTP headers */
-
+
http_header_line = emalloc(HTTP_HEADER_BLOCK_SIZE);
while (!body && !php_stream_eof(stream)) {
@@ -738,7 +742,7 @@ finish:
follow_location = Z_LVAL_PP(tmpzval);
} else if (!(response_code >= 300 && response_code < 304 || 307 == response_code || 308 == response_code)) {
/* we shouldn't redirect automatically
- if follow_location isn't set and response_code not in (300, 301, 302, 303 and 307)
+ if follow_location isn't set and response_code not in (300, 301, 302, 303 and 307)
see http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.1
RFC 7238 defines 308: http://tools.ietf.org/html/rfc7238 */
follow_location = 0;
@@ -778,7 +782,7 @@ finish:
MAKE_STD_ZVAL(http_header);
ZVAL_STRINGL(http_header, http_header_line, http_header_line_length, 1);
-
+
zend_hash_next_index_insert(Z_ARRVAL_P(response_header), &http_header, sizeof(zval *), NULL);
}
} else {
@@ -803,10 +807,10 @@ finish:
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) &&
- strncasecmp(location, "ftp://", sizeof("ftp://")-1) &&
- strncasecmp(location, "ftps://", sizeof("ftps://")-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) {
@@ -820,7 +824,7 @@ finish:
*s = '/';
}
}
- s[1] = '\0';
+ s[1] = '\0';
if (resource->path && *(resource->path) == '/' && *(resource->path + 1) == '\0') {
snprintf(loc_path, sizeof(loc_path) - 1, "%s%s", resource->path, location);
} else {
@@ -893,18 +897,21 @@ out:
if (stream) {
if (header_init) {
- zval_add_ref(&response_header);
stream->wrapperdata = response_header;
+ } else {
+ if(response_header) {
+ Z_DELREF_P(response_header);
+ }
}
php_stream_notify_progress_init(context, 0, file_size);
-
+
/* Restore original chunk size now that we're done with headers */
if (options & STREAM_WILL_CAST)
php_stream_set_chunk_size(stream, chunk_size);
/* restore the users auto-detect-line-endings setting */
stream->flags |= eol_detect;
-
+
/* as far as streams are concerned, we are now at the start of
* the stream */
stream->position = 0;
@@ -915,8 +922,13 @@ out:
if (transfer_encoding) {
php_stream_filter_append(&stream->readfilters, transfer_encoding);
}
- } else if (transfer_encoding) {
- php_stream_filter_free(transfer_encoding TSRMLS_CC);
+ } else {
+ if(response_header) {
+ Z_DELREF_P(response_header);
+ }
+ if (transfer_encoding) {
+ php_stream_filter_free(transfer_encoding TSRMLS_CC);
+ }
}
return stream;
diff --git a/ext/standard/link.c b/ext/standard/link.c
index c57484e766..686dd3e306 100644
--- a/ext/standard/link.c
+++ b/ext/standard/link.c
@@ -59,7 +59,7 @@ PHP_FUNCTION(readlink)
char buff[MAXPATHLEN];
int ret;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &link, &link_len) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p", &link, &link_len) == FAILURE) {
return;
}
diff --git a/ext/standard/streamsfuncs.c b/ext/standard/streamsfuncs.c
index b1b318044e..b8f15e32c2 100644
--- a/ext/standard/streamsfuncs.c
+++ b/ext/standard/streamsfuncs.c
@@ -1549,7 +1549,7 @@ PHP_FUNCTION(stream_resolve_include_path)
char *filename, *resolved_path;
int filename_len;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &filename, &filename_len) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p", &filename, &filename_len) == FAILURE) {
return;
}
diff --git a/ext/standard/tests/file/readlink_variation1.phpt b/ext/standard/tests/file/readlink_variation1.phpt
index 1dae17cbd4..d4f1a5ff02 100644
--- a/ext/standard/tests/file/readlink_variation1.phpt
+++ b/ext/standard/tests/file/readlink_variation1.phpt
@@ -65,7 +65,7 @@ bool(false)
Warning: readlink(): %s in %s on line %d
bool(false)
-Warning: readlink() expects parameter 1 to be string, resource given in %s on line %d
+Warning: readlink() expects parameter 1 to be a valid path, resource given in %s on line %d
NULL
Warning: readlink(): %s in %s on line %d
diff --git a/ext/standard/tests/http/bug69337.phpt b/ext/standard/tests/http/bug69337.phpt
new file mode 100644
index 0000000000..1451d4bf01
--- /dev/null
+++ b/ext/standard/tests/http/bug69337.phpt
@@ -0,0 +1,41 @@
+--TEST--
+Bug #69337 (Stream context leaks when http request fails)
+--SKIPIF--
+<?php require 'server.inc'; http_server_skipif('tcp://127.0.0.1:22345'); ?>
+--INI--
+allow_url_fopen=1
+allow_url_include=1
+--FILE--
+<?php
+require 'server.inc';
+
+function stream_notification_callback($notification_code, $severity, $message, $message_code, $bytes_transferred, $bytes_max)
+{
+ if($notification_code == STREAM_NOTIFY_REDIRECTED) {
+ // $http_response_header is now a string, but will be used as an array
+ // by php_stream_url_wrap_http_ex() later on
+ $GLOBALS['http_response_header'] = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\0\0\0\0";
+ }
+}
+
+$ctx = stream_context_create();
+stream_context_set_params($ctx, array("notification" => "stream_notification_callback"));
+
+$responses = array(
+ "data://text/plain,HTTP/1.0 302 Found\r\nLocation: http://127.0.0.1:22345/try-again\r\n\r\n",
+ "data://text/plain,HTTP/1.0 404 Not Found\r\n\r\n",
+);
+
+$pid = http_server("tcp://127.0.0.1:22345", $responses, $output);
+
+$f = file_get_contents('http://127.0.0.1:22345/', 0, $ctx);
+
+http_server_kill($pid);
+var_dump($f);
+?>
+==DONE==
+--EXPECTF--
+string(26) "HTTP/1.0 404 Not Found
+
+"
+==DONE== \ No newline at end of file
diff --git a/ext/standard/tests/serialize/bug69152.phpt b/ext/standard/tests/serialize/bug69152.phpt
new file mode 100644
index 0000000000..4e741685cc
--- /dev/null
+++ b/ext/standard/tests/serialize/bug69152.phpt
@@ -0,0 +1,16 @@
+--TEST--
+Bug #69152: Type Confusion Infoleak Vulnerability in unserialize()
+--FILE--
+<?php
+$x = unserialize('O:9:"exception":1:{s:16:"'."\0".'Exception'."\0".'trace";s:4:"ryat";}');
+echo $x;
+$x = unserialize('O:4:"test":1:{s:27:"__PHP_Incomplete_Class_Name";R:1;}');
+$x->test();
+
+?>
+--EXPECTF--
+exception 'Exception' in %s:%d
+Stack trace:
+#0 {main}
+
+Fatal error: main(): The script tried to execute a method or access a property of an incomplete object. Please ensure that the class definition "unknown" of the object you are trying to operate on was loaded _before_ unserialize() gets called or provide a __autoload() function to load the class definition in %s on line %d
diff --git a/ext/xmlwriter/php_xmlwriter.c b/ext/xmlwriter/php_xmlwriter.c
index 7bc35dabc4..acb87541d8 100644
--- a/ext/xmlwriter/php_xmlwriter.c
+++ b/ext/xmlwriter/php_xmlwriter.c
@@ -1738,7 +1738,7 @@ static PHP_FUNCTION(xmlwriter_write_dtd_entity)
/* }}} */
#endif
-/* {{{ proto resource xmlwriter_open_uri(resource xmlwriter, string source)
+/* {{{ proto resource xmlwriter_open_uri(string source)
Create new xmlwriter using source uri for output */
static PHP_FUNCTION(xmlwriter_open_uri)
{
@@ -1759,7 +1759,7 @@ static PHP_FUNCTION(xmlwriter_open_uri)
void *ioctx;
#endif
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &source, &source_len) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p", &source, &source_len) == FAILURE) {
return;
}
diff --git a/ext/zlib/tests/gzopen_variation1.phpt b/ext/zlib/tests/gzopen_variation1.phpt
index c5a47f4d08..bca48f39c9 100644
--- a/ext/zlib/tests/gzopen_variation1.phpt
+++ b/ext/zlib/tests/gzopen_variation1.phpt
@@ -1,17 +1,17 @@
--TEST--
-Test gzopen() function : usage variation
+Test gzopen() function : usage variation
--SKIPIF--
-<?php
+<?php
if (!extension_loaded("zlib")) {
- print "skip - zlib extension not loaded";
-}
+ print "skip - zlib extension not loaded";
+}
?>
--FILE--
<?php
/* Prototype : resource gzopen(string filename, string mode [, int use_include_path])
- * Description: Open a .gz-file and return a .gz-file pointer
+ * Description: Open a .gz-file and return a .gz-file pointer
* Source code: ext/zlib/zlib.c
- * Alias to functions:
+ * Alias to functions:
*/
echo "*** Testing gzopen() : usage variation ***\n";
@@ -102,9 +102,9 @@ $inputs = array(
// unset data
'unset var' => @$unset_var,
-
+
// resource variable
- 'resource' => $fp
+ 'resource' => $fp
);
// loop through each element of the array for filename
@@ -158,19 +158,19 @@ Error: 2 - gzopen(0.5): failed to open stream: No such file or directory, %s(%d)
bool(false)
--empty array--
-Error: 2 - gzopen() expects parameter 1 to be string, array given, %s(%d)
+Error: 2 - gzopen() expects parameter 1 to be a valid path, array given, %s(%d)
NULL
--int indexed array--
-Error: 2 - gzopen() expects parameter 1 to be string, array given, %s(%d)
+Error: 2 - gzopen() expects parameter 1 to be a valid path, array given, %s(%d)
NULL
--associative array--
-Error: 2 - gzopen() expects parameter 1 to be string, array given, %s(%d)
+Error: 2 - gzopen() expects parameter 1 to be a valid path, array given, %s(%d)
NULL
--nested arrays--
-Error: 2 - gzopen() expects parameter 1 to be string, array given, %s(%d)
+Error: 2 - gzopen() expects parameter 1 to be a valid path, array given, %s(%d)
NULL
--uppercase NULL--
@@ -210,7 +210,7 @@ Error: 2 - gzopen(Class A object): failed to open stream: No such file or direct
bool(false)
--instance of classWithoutToString--
-Error: 2 - gzopen() expects parameter 1 to be string, object given, %s(%d)
+Error: 2 - gzopen() expects parameter 1 to be a valid path, object given, %s(%d)
NULL
--undefined var--
@@ -222,7 +222,7 @@ Error: 2 - gzopen(): Filename cannot be empty, %s(%d)
bool(false)
--resource--
-Error: 2 - gzopen() expects parameter 1 to be string, resource given, %s(%d)
+Error: 2 - gzopen() expects parameter 1 to be a valid path, resource given, %s(%d)
NULL
===DONE===
diff --git a/ext/zlib/tests/readgzfile_variation1.phpt b/ext/zlib/tests/readgzfile_variation1.phpt
index 5a5ec4f6e7..5d9b639d29 100644
--- a/ext/zlib/tests/readgzfile_variation1.phpt
+++ b/ext/zlib/tests/readgzfile_variation1.phpt
@@ -29,15 +29,15 @@ foreach ( $variation as $var ) {
===DONE===
--EXPECTF--
-Warning: readgzfile() expects parameter 1 to be string, array given in %s on line %d
+Warning: readgzfile() expects parameter 1 to be a valid path, array given in %s on line %d
NULL
-Warning: readgzfile() expects parameter 1 to be string, array given in %s on line %d
+Warning: readgzfile() expects parameter 1 to be a valid path, array given in %s on line %d
NULL
-Warning: readgzfile() expects parameter 1 to be string, array given in %s on line %d
+Warning: readgzfile() expects parameter 1 to be a valid path, array given in %s on line %d
NULL
-Warning: readgzfile() expects parameter 1 to be string, array given in %s on line %d
+Warning: readgzfile() expects parameter 1 to be a valid path, array given in %s on line %d
NULL
-===DONE=== \ No newline at end of file
+===DONE===
diff --git a/ext/zlib/tests/readgzfile_variation6.phpt b/ext/zlib/tests/readgzfile_variation6.phpt
index 702f91850e..9fcea02939 100644
--- a/ext/zlib/tests/readgzfile_variation6.phpt
+++ b/ext/zlib/tests/readgzfile_variation6.phpt
@@ -45,5 +45,5 @@ foreach ( $variation as $var ) {
--EXPECTF--
Error: 2 - readgzfile(Class A object): failed to open stream: No such file or directory, %s(%d)
bool(false)
-Error: 2 - readgzfile() expects parameter 1 to be string, object given, %s(%d)
-NULL \ No newline at end of file
+Error: 2 - readgzfile() expects parameter 1 to be a valid path, object given, %s(%d)
+NULL
diff --git a/ext/zlib/zlib.c b/ext/zlib/zlib.c
index 705fb5dd5f..431dfde547 100644
--- a/ext/zlib/zlib.c
+++ b/ext/zlib/zlib.c
@@ -581,7 +581,7 @@ static PHP_FUNCTION(gzopen)
php_stream *stream;
long use_include_path = 0;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|l", &filename, &filename_len, &mode, &mode_len, &use_include_path) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ps|l", &filename, &filename_len, &mode, &mode_len, &use_include_path) == FAILURE) {
return;
}
@@ -609,7 +609,7 @@ static PHP_FUNCTION(readgzfile)
int size;
long use_include_path = 0;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &filename, &filename_len, &use_include_path) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p|l", &filename, &filename_len, &use_include_path) == FAILURE) {
return;
}
diff --git a/sapi/apache2handler/sapi_apache2.c b/sapi/apache2handler/sapi_apache2.c
index e97f11c69b..cfebc5f5c6 100644
--- a/sapi/apache2handler/sapi_apache2.c
+++ b/sapi/apache2handler/sapi_apache2.c
@@ -688,6 +688,7 @@ zend_first_try {
} zend_end_try();
}
apr_brigade_cleanup(brigade);
+ apr_pool_cleanup_run(r->pool, (void *)&SG(server_context), php_server_context_cleanup);
} else {
ctx->r = parent_req;
}