diff options
| -rw-r--r-- | NEWS | 4 | ||||
| -rw-r--r-- | ext/standard/tests/file/bug39673.phpt | 40 | ||||
| -rw-r--r-- | main/streams/plain_wrapper.c | 7 |
3 files changed, 50 insertions, 1 deletions
@@ -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; |
