]> granicus.if.org Git - php/commitdiff
Fixed bug #69100
authorNikita Popov <nikita.ppv@gmail.com>
Wed, 17 Jul 2019 13:58:29 +0000 (15:58 +0200)
committerNikita Popov <nikita.ppv@gmail.com>
Wed, 17 Jul 2019 13:58:29 +0000 (15:58 +0200)
NEWS
ext/standard/tests/file/bug69100.phpt [new file with mode: 0644]
main/streams/plain_wrapper.c

diff --git a/NEWS b/NEWS
index a29cf2dd0d26c792cfe6d07cb4570dec2a689883..4e37d391b71057cde8e231155bd59cc6f4f96818 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,10 @@ PHP                                                                        NEWS
 |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
 ?? ??? 2019, PHP 7.2.22
 
+- Standard:
+  . Fixed bug #69100 (Bus error from stream_copy_to_stream (file -> SSL stream)
+    with invalid length). (Nikita)
+
 01 Aug 2019, PHP 7.2.21
 
 - Fileinfo:
diff --git a/ext/standard/tests/file/bug69100.phpt b/ext/standard/tests/file/bug69100.phpt
new file mode 100644 (file)
index 0000000..b243bfc
--- /dev/null
@@ -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)
index d409fe99f06f2c10eda4d010823d9fbc0c728175..837485742a207ff8701e02aaf41cdf3065fefde2 100644 (file)
@@ -696,18 +696,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: