summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NEWS4
-rw-r--r--ext/standard/tests/file/bug39673.phpt40
-rw-r--r--main/streams/plain_wrapper.c7
3 files changed, 50 insertions, 1 deletions
diff --git a/NEWS b/NEWS
index 77e201c533..a997c15e12 100644
--- a/NEWS
+++ b/NEWS
@@ -43,8 +43,10 @@ PHP NEWS
php_filter.h).
- Fixed wrong signature initialization in imagepng (Takeshi Abe)
- Added optimization for imageline with horizontal and vertial lines (Pierre)
-- Fixed bug #39662 (Segfault when calling asXML() of a cloned SimpleXMLElement).
+- Fixed bug #39673 (file_get_contents causes bus error on certain offsets).
(Tony)
+- Fixed bug #39662 (Segfault when calling asXML() of a cloned SimpleXMLElement).
+ (Rob, Tony)
- Fixed bug #39656 (crash when calling fetch() on a PDO statment object
after closeCursor()). (Ilia, Tony)
- Fixed bug #39653 (ext/dba doesn't check for db-4.5 and db-4.4 when db4
diff --git a/ext/standard/tests/file/bug39673.phpt b/ext/standard/tests/file/bug39673.phpt
new file mode 100644
index 0000000000..3836f2103d
--- /dev/null
+++ b/ext/standard/tests/file/bug39673.phpt
@@ -0,0 +1,40 @@
+--TEST--
+Bug #39673 (file_get_contents causes bus error on certain offsets)
+--FILE--
+<?php
+
+$str = str_repeat("test", 3456);
+
+$filename = dirname(__FILE__).'/bug39673.txt';
+file_put_contents($filename, $str);
+
+$offsets = array(
+ -1,
+ 0,
+ 3456*4,
+ 3456*4 - 1,
+ 3456*4 + 1,
+ 2000,
+ 5000,
+ 100000,
+);
+
+
+foreach ($offsets as $offset) {
+ $r = file_get_contents($filename, false, null, $offset);
+ var_dump(strlen($r));
+}
+
+@unlink($filename);
+echo "Done\n";
+?>
+--EXPECTF--
+int(13824)
+int(13824)
+int(0)
+int(1)
+int(0)
+int(11824)
+int(8824)
+int(0)
+Done
diff --git a/main/streams/plain_wrapper.c b/main/streams/plain_wrapper.c
index f268eaf07c..5bcbe6170b 100644
--- a/main/streams/plain_wrapper.c
+++ b/main/streams/plain_wrapper.c
@@ -627,9 +627,16 @@ static int php_stdiop_set_option(php_stream *stream, int option, int value, void
case PHP_STREAM_MMAP_MAP_RANGE:
do_fstat(data, 1);
+ 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) {
+ range->offset = data->sb.st_size;
+ range->length = 0;
+ }
switch (range->mode) {
case PHP_STREAM_MAP_MODE_READONLY:
prot = PROT_READ;