mirror of
https://github.com/php/php-src.git
synced 2025-08-15 21:48:51 +02:00
Fix GH-13203: file_put_contents fail on strings over 4GB on Windows
Closes GH-13205
This commit is contained in:
parent
a284c3e873
commit
2343791aff
3 changed files with 71 additions and 5 deletions
2
NEWS
2
NEWS
|
@ -32,6 +32,8 @@ PHP NEWS
|
||||||
. Fixed bug GH-11808 (Live filesystem modified by tests). (nielsdos)
|
. Fixed bug GH-11808 (Live filesystem modified by tests). (nielsdos)
|
||||||
. Fixed GH-13402 (Added validation of `\n` in $additional_headers of mail()).
|
. Fixed GH-13402 (Added validation of `\n` in $additional_headers of mail()).
|
||||||
(SakiTakamachi)
|
(SakiTakamachi)
|
||||||
|
. Fixed bug GH-13203 (file_put_contents fail on strings over 4GB on Windows).
|
||||||
|
(divinity76)
|
||||||
|
|
||||||
- XML:
|
- XML:
|
||||||
. Fixed bug GH-13517 (Multiple test failures when building with
|
. Fixed bug GH-13517 (Multiple test failures when building with
|
||||||
|
|
67
ext/standard/tests/file/file_put_contents_5gb.phpt
Normal file
67
ext/standard/tests/file/file_put_contents_5gb.phpt
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
--TEST--
|
||||||
|
Test file_put_contents() function with 5GB string
|
||||||
|
--SKIPIF--
|
||||||
|
<?php
|
||||||
|
if (PHP_INT_SIZE < 5) {
|
||||||
|
// 4=4gb, 5=549gb, 8=9exabytes
|
||||||
|
skip("skip PHP_INT_SIZE<5 will not fit test string in RAM");
|
||||||
|
}
|
||||||
|
if (getenv('SKIP_SLOW_TESTS')) {
|
||||||
|
die('skip slow test');
|
||||||
|
}
|
||||||
|
function get_system_memory(): int|float|false
|
||||||
|
{
|
||||||
|
if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
|
||||||
|
// Windows-based memory check
|
||||||
|
@exec('wmic OS get FreePhysicalMemory', $output);
|
||||||
|
if (isset($output[1])) {
|
||||||
|
return ((int)trim($output[1])) * 1024;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Unix/Linux-based memory check
|
||||||
|
$memInfo = @file_get_contents("/proc/meminfo");
|
||||||
|
if ($memInfo) {
|
||||||
|
preg_match('/MemFree:\s+(\d+) kB/', $memInfo, $matches);
|
||||||
|
return $matches[1] * 1024; // Convert to bytes
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (get_system_memory() < 10 * 1024 * 1024 * 1024) {
|
||||||
|
die('skip Reason: Insufficient RAM (less than 10GB)');
|
||||||
|
}
|
||||||
|
$tmpfile = sys_get_temp_dir() . DIRECTORY_SEPARATOR . "test_file_put_contents_5gb.bin";
|
||||||
|
$tmpfileh = fopen($tmpfile, "wb");
|
||||||
|
if ($tmpfileh === false) {
|
||||||
|
die('skip Reason: Unable to create temporary file');
|
||||||
|
}
|
||||||
|
fclose($tmpfileh);
|
||||||
|
unlink($tmpfile);
|
||||||
|
if (disk_free_space(dirname($tmpfile)) < 10 * 1024 * 1024 * 1024) {
|
||||||
|
die('skip Reason: Insufficient disk space (less than 10GB)');
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
--INI--
|
||||||
|
memory_limit=6G
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
$tmpfile = sys_get_temp_dir() . DIRECTORY_SEPARATOR . "test_file_put_contents_5gb.bin";
|
||||||
|
$large_string = str_repeat('a', 5 * 1024 * 1024 * 1024);
|
||||||
|
$result = file_put_contents($tmpfile, $large_string);
|
||||||
|
if ($result !== strlen($large_string)) {
|
||||||
|
echo "Could only write $result bytes of " . strlen($large_string) . " bytes.";
|
||||||
|
var_dump(error_get_last());
|
||||||
|
} else {
|
||||||
|
echo "File written successfully.";
|
||||||
|
}
|
||||||
|
clearstatcache(true, $tmpfile);
|
||||||
|
if (file_exists($tmpfile)) {
|
||||||
|
unlink($tmpfile);
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
--CLEAN--
|
||||||
|
<?php
|
||||||
|
@unlink(sys_get_temp_dir() . DIRECTORY_SEPARATOR . "test_file_put_contents_5gb.bin");
|
||||||
|
?>
|
||||||
|
--EXPECT--
|
||||||
|
File written successfully.
|
|
@ -40,6 +40,7 @@
|
||||||
# include "win32/time.h"
|
# include "win32/time.h"
|
||||||
# include "win32/ioutil.h"
|
# include "win32/ioutil.h"
|
||||||
# include "win32/readdir.h"
|
# include "win32/readdir.h"
|
||||||
|
# include <limits.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define php_stream_fopen_from_fd_int(fd, mode, persistent_id) _php_stream_fopen_from_fd_int((fd), (mode), (persistent_id) STREAMS_CC)
|
#define php_stream_fopen_from_fd_int(fd, mode, persistent_id) _php_stream_fopen_from_fd_int((fd), (mode), (persistent_id) STREAMS_CC)
|
||||||
|
@ -353,11 +354,7 @@ static ssize_t php_stdiop_write(php_stream *stream, const char *buf, size_t coun
|
||||||
|
|
||||||
if (data->fd >= 0) {
|
if (data->fd >= 0) {
|
||||||
#ifdef PHP_WIN32
|
#ifdef PHP_WIN32
|
||||||
ssize_t bytes_written;
|
ssize_t bytes_written = _write(data->fd, buf, (unsigned int)(count > INT_MAX ? INT_MAX : count));
|
||||||
if (ZEND_SIZE_T_UINT_OVFL(count)) {
|
|
||||||
count = UINT_MAX;
|
|
||||||
}
|
|
||||||
bytes_written = _write(data->fd, buf, (unsigned int)count);
|
|
||||||
#else
|
#else
|
||||||
ssize_t bytes_written = write(data->fd, buf, count);
|
ssize_t bytes_written = write(data->fd, buf, count);
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue