Bug #81145 [NEW]: copy() and stream_copy_to_stream() fail for +4GB files
| From: | php at bitm dot sg | Date: | Wed, 16 Jun 2021 09:43:27 +0000 |
| Subject: | Bug #81145 [NEW]: copy() and stream_copy_to_stream() fail for +4GB files | ||
| Groups: | php.bugs | ||
| Request: | Send a blank email to php-bugs+get-234428@lists.php.net to get a copy of this message | ||
From: php at bitm dot sg
Operating system: Microsoft Windows [Version 1 x64
PHP version: 8.0.7
Package: Filesystem function related
Bug Type: Bug
Bug description:copy() and stream_copy_to_stream() fail for +4GB files
Description:
------------
Using copy() or stream_copy_to_stream() fails on Windows with files over
4GB, even if the underlying volume (NTFS) supports it and Windows + PHP
are 64 bit.
Test script:
---------------
<?php
//Both files must be on an NTFS volume. You may use the same volume.
$src='C:/temp/4G.src.bin';
$dst='C:/temp/4G.dst.bin';
define('SIZE_4G',0x100000000);
@unlink($src);
//Create file and append random content at the 4GB boundary
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);
Expected result:
----------------
The functions should copy files and streams as-is and the script should
print "Identical"
Actual result:
--------------
Script prints "Copy failed"
Only the first 4 GB of the source file are copied.
This is actually done repeatedly until the destination is as large as
the source. So if the file is 13 GB, the destination will contain the
first 4 GB of the source 3 times, followed by the first GB again.
using "fwrite($b,fread($a,$buffer))" to manually copy files works.
--
Edit bug report at https://bugs.php.net/bug.php?id=81145&edit=1
--
Fix committed: https://bugs.php.net/fix.php?id=81145&r=fixed
Fixed in release: https://bugs.php.net/fix.php?id=81145&r=alreadyfixed
Need backtrace: https://bugs.php.net/fix.php?id=81145&r=needtrace
Need Reproduce Script: https://bugs.php.net/fix.php?id=81145&r=needscript
Try newer version: https://bugs.php.net/fix.php?id=81145&r=oldversion
Not developer issue: https://bugs.php.net/fix.php?id=81145&r=support
Expected behavior: https://bugs.php.net/fix.php?id=81145&r=notwrong
Not enough info: https://bugs.php.net/fix.php?id=81145&r=notenoughinfo
Submitted twice: https://bugs.php.net/fix.php?id=81145&r=submittedtwice
register_globals: https://bugs.php.net/fix.php?id=81145&r=globals
PHP version support discontinued: https://bugs.php.net/fix.php?id=81145&r=phptooold
Daylight Savings: https://bugs.php.net/fix.php?id=81145&r=dst
IIS Stability: https://bugs.php.net/fix.php?id=81145&r=isapi
Install GNU Sed: https://bugs.php.net/fix.php?id=81145&r=gnused
Floating point limitations: https://bugs.php.net/fix.php?id=81145&r=float
No Zend Extensions: https://bugs.php.net/fix.php?id=81145&r=nozend
MySQL Configuration Error: https://bugs.php.net/fix.php?id=81145&r=mysqlcfg