mirror of
https://github.com/php/php-src.git
synced 2025-08-15 21:48:51 +02:00
Merge branch 'PHP-8.0'
* PHP-8.0: Fix #81145: copy() and stream_copy_to_stream() fail for +4GB files
This commit is contained in:
commit
83517340f6
2 changed files with 55 additions and 4 deletions
48
ext/standard/tests/file/bug81145.phpt
Normal file
48
ext/standard/tests/file/bug81145.phpt
Normal file
|
@ -0,0 +1,48 @@
|
|||
--TEST--
|
||||
Bug #81145 (copy() and stream_copy_to_stream() fail for +4GB files)
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (getenv("SKIP_SLOW_TESTS")) die("skip slow test");
|
||||
if (PHP_INT_SIZE !== 8) die("skip this test is for 64bit platforms only");
|
||||
if (disk_free_space(__DIR__) < 0x220000000) die("skip insuffient disk space");
|
||||
if (PHP_OS_FAMILY !== "Windows") {
|
||||
exec("fallocate -h", $output, $status);
|
||||
if ($status !== 0) die("skip fallocate(1) not available");
|
||||
}
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
$src = __DIR__ . "/bug81145_src.bin";
|
||||
$dst = __DIR__ . "/bug81145_dst.bin";
|
||||
define('SIZE_4G', 0x100000000);
|
||||
|
||||
//Create file and append random content at the 4GB boundary
|
||||
if (PHP_OS_FAMILY !== "Windows") {
|
||||
exec("fallocate -l " . (SIZE_4G-0x100) . " " . escapeshellarg($src));
|
||||
} else {
|
||||
exec("fsutil file createnew " . escapeshellarg($src) . " " . (SIZE_4G-0x100));
|
||||
}
|
||||
$fp = fopen($src, "ab");
|
||||
fwrite($fp, random_bytes(0x200));
|
||||
fclose($fp);
|
||||
copy($src, $dst);
|
||||
if (filesize($src) !== filesize($dst)) {
|
||||
die("Files have different sizes!");
|
||||
}
|
||||
$f1 = fopen($src,'rb') or die("src open failed");
|
||||
$f2 = fopen($dst,'rb') or die("dst open failed");
|
||||
|
||||
//Seek to 4 GB boundary, as this is the location where the problem occurs
|
||||
fseek($f1, SIZE_4G - 0x100, SEEK_SET);
|
||||
fseek($f2, SIZE_4G - 0x100, SEEK_SET);
|
||||
echo (fread($f1,0x200) === fread($f2,0x200) ? "Identical" : "Copy failed");
|
||||
fclose($f1);
|
||||
fclose($f2);
|
||||
?>
|
||||
--CLEAN--
|
||||
<?php
|
||||
@unlink(__DIR__ . "/bug81145_src.bin");
|
||||
@unlink(__DIR__ . "/bug81145_dst.bin");
|
||||
?>
|
||||
--EXPECT--
|
||||
Identical
|
|
@ -807,7 +807,7 @@ static int php_stdiop_set_option(php_stream *stream, int option, int value, void
|
|||
{
|
||||
php_stream_mmap_range *range = (php_stream_mmap_range*)ptrparam;
|
||||
HANDLE hfile = (HANDLE)_get_osfhandle(fd);
|
||||
DWORD prot, acc, loffs = 0, delta = 0;
|
||||
DWORD prot, acc, loffs = 0, hoffs = 0, delta = 0;
|
||||
LARGE_INTEGER file_size;
|
||||
|
||||
switch (value) {
|
||||
|
@ -875,8 +875,11 @@ static int php_stdiop_set_option(php_stream *stream, int option, int value, void
|
|||
|
||||
GetSystemInfo(&info);
|
||||
gran = info.dwAllocationGranularity;
|
||||
loffs = ((DWORD)range->offset / gran) * gran;
|
||||
delta = (DWORD)range->offset - loffs;
|
||||
ZEND_ASSERT(gran != 0 && (gran & (gran - 1)) == 0);
|
||||
size_t rounded_offset = (range->offset / gran) * gran;
|
||||
delta = range->offset - rounded_offset;
|
||||
loffs = (DWORD)rounded_offset;
|
||||
hoffs = (DWORD)(rounded_offset >> 32);
|
||||
}
|
||||
|
||||
/* MapViewOfFile()ing zero bytes would map to the end of the file; match *nix behavior instead */
|
||||
|
@ -884,7 +887,7 @@ static int php_stdiop_set_option(php_stream *stream, int option, int value, void
|
|||
return PHP_STREAM_OPTION_RETURN_ERR;
|
||||
}
|
||||
|
||||
data->last_mapped_addr = MapViewOfFile(data->file_mapping, acc, 0, loffs, range->length + delta);
|
||||
data->last_mapped_addr = MapViewOfFile(data->file_mapping, acc, hoffs, loffs, range->length + delta);
|
||||
|
||||
if (data->last_mapped_addr) {
|
||||
/* give them back the address of the start offset they requested */
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue