summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NEWS4
-rw-r--r--ext/standard/tests/file/bug69100.phpt24
-rw-r--r--main/streams/plain_wrapper.c15
3 files changed, 34 insertions, 9 deletions
diff --git a/NEWS b/NEWS
index dd12d6d9e4..5ce6212a05 100644
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,10 @@ PHP NEWS
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
?? ??? ????, PHP 7.3.9
+- Standard:
+ . Fixed bug #69100 (Bus error from stream_copy_to_stream (file -> SSL stream)
+ with invalid length). (Nikita)
+
01 Aug 2019, PHP 7.3.8
- Core:
diff --git a/ext/standard/tests/file/bug69100.phpt b/ext/standard/tests/file/bug69100.phpt
new file mode 100644
index 0000000000..b243bfc3a0
--- /dev/null
+++ b/ext/standard/tests/file/bug69100.phpt
@@ -0,0 +1,24 @@
+--TEST--
+Bug #69100: Bus error from stream_copy_to_stream (file -> SSL stream) with invalid length
+--FILE--
+<?php
+
+$fileIn = __DIR__ . '/bug69100_in.txt';
+$fileOut = __DIR__ . '/bug69100_out.txt';
+
+file_put_contents($fileIn, str_repeat('A', 64 * 1024));
+$fr = fopen($fileIn, 'rb');
+$fw = fopen($fileOut, 'w');
+
+var_dump(stream_copy_to_stream($fr, $fw, 32 * 1024));
+var_dump(stream_copy_to_stream($fr, $fw, 64 * 1024));
+
+fclose($fr);
+fclose($fw);
+unlink($fileIn);
+unlink($fileOut);
+
+?>
+--EXPECT--
+int(32768)
+int(32768)
diff --git a/main/streams/plain_wrapper.c b/main/streams/plain_wrapper.c
index 785da8743b..c975997981 100644
--- a/main/streams/plain_wrapper.c
+++ b/main/streams/plain_wrapper.c
@@ -694,18 +694,15 @@ static int php_stdiop_set_option(php_stream *stream, int option, int value, void
return fd == -1 ? PHP_STREAM_OPTION_RETURN_ERR : PHP_STREAM_OPTION_RETURN_OK;
case PHP_STREAM_MMAP_MAP_RANGE:
- if(do_fstat(data, 1) != 0) {
+ if (do_fstat(data, 1) != 0) {
return PHP_STREAM_OPTION_RETURN_ERR;
}
- if (range->length == 0 && range->offset > 0 && range->offset < data->sb.st_size) {
- range->length = data->sb.st_size - range->offset;
- }
- if (range->length == 0 || range->length > data->sb.st_size) {
- range->length = data->sb.st_size;
- }
- if (range->offset >= data->sb.st_size) {
+ if (range->offset > data->sb.st_size) {
range->offset = data->sb.st_size;
- range->length = 0;
+ }
+ if (range->length == 0 ||
+ range->length > data->sb.st_size - range->offset) {
+ range->length = data->sb.st_size - range->offset;
}
switch (range->mode) {
case PHP_STREAM_MAP_MODE_READONLY: