From 44e88297b99ff30b0f15feef76321004b7587285 Mon Sep 17 00:00:00 2001 From: divinity76 Date: Sat, 20 Jan 2024 19:38:49 +0100 Subject: [PATCH 01/18] fix GH-13203 file_put_contents fail on strings over 4GB on Windows --- main/streams/plain_wrapper.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main/streams/plain_wrapper.c b/main/streams/plain_wrapper.c index 86c517132482e..92f973bbfae17 100644 --- a/main/streams/plain_wrapper.c +++ b/main/streams/plain_wrapper.c @@ -357,7 +357,7 @@ static ssize_t php_stdiop_write(php_stream *stream, const char *buf, size_t coun if (ZEND_SIZE_T_UINT_OVFL(count)) { count = UINT_MAX; } - bytes_written = _write(data->fd, buf, (unsigned int)count); + bytes_written = _write(data->fd, buf, (unsigned int)((count > UINT_MAX) ? UINT_MAX : count)); #else ssize_t bytes_written = write(data->fd, buf, count); #endif From 1158cb13e31321cc137a5c50cad2e31b29344061 Mon Sep 17 00:00:00 2001 From: divinity76 Date: Sat, 20 Jan 2024 19:40:56 +0100 Subject: [PATCH 02/18] forgot limits.h --- main/streams/plain_wrapper.c | 1 + 1 file changed, 1 insertion(+) diff --git a/main/streams/plain_wrapper.c b/main/streams/plain_wrapper.c index 92f973bbfae17..467a7361895e6 100644 --- a/main/streams/plain_wrapper.c +++ b/main/streams/plain_wrapper.c @@ -40,6 +40,7 @@ # include "win32/time.h" # include "win32/ioutil.h" # include "win32/readdir.h" +#include #endif #define php_stream_fopen_from_fd_int(fd, mode, persistent_id) _php_stream_fopen_from_fd_int((fd), (mode), (persistent_id) STREAMS_CC) From f4424ea7916e9f61919a7000cca3633db4fefb8d Mon Sep 17 00:00:00 2001 From: divinity76 Date: Sat, 20 Jan 2024 20:22:45 +0100 Subject: [PATCH 03/18] Create file_put_contents_5gb.phpt --- .../tests/file/file_put_contents_5gb.phpt | 63 +++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 ext/standard/tests/file/file_put_contents_5gb.phpt diff --git a/ext/standard/tests/file/file_put_contents_5gb.phpt b/ext/standard/tests/file/file_put_contents_5gb.phpt new file mode 100644 index 0000000000000..fbbe430857ed4 --- /dev/null +++ b/ext/standard/tests/file/file_put_contents_5gb.phpt @@ -0,0 +1,63 @@ +--TEST-- +Test file_put_contents() function with 5GB string +--SKIPIF-- + + +--INI-- +memory_limit=6G + +--FILE-- + + +--EXPECT-- +File written successfully. From c6b5b3da834a829d98914324011cad63e7993b3f Mon Sep 17 00:00:00 2001 From: divinity76 Date: Sat, 20 Jan 2024 20:43:59 +0100 Subject: [PATCH 04/18] fix wmic invocation --- ext/standard/tests/file/file_put_contents_5gb.phpt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/standard/tests/file/file_put_contents_5gb.phpt b/ext/standard/tests/file/file_put_contents_5gb.phpt index fbbe430857ed4..0b29be1803602 100644 --- a/ext/standard/tests/file/file_put_contents_5gb.phpt +++ b/ext/standard/tests/file/file_put_contents_5gb.phpt @@ -10,7 +10,7 @@ function get_system_memory(): int|float|false { if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') { // Windows-based memory check - @exec('wmic ComputerSystem get AvailablePhysicalMemory', $output); + @exec('wmic OS get FreePhysicalMemory', $output); if (isset($output[1])) { return (int)trim($output[1]); } From a2aeff277dd00f16475bc0aa968f51107f81f5d6 Mon Sep 17 00:00:00 2001 From: divinity76 Date: Sat, 20 Jan 2024 22:59:27 +0100 Subject: [PATCH 05/18] PLAIN_WRAP_BUF_SIZE actually exist a macro to do the cast (not implemented exactly how I would have preferred, but it's fine. is UINT_MAX actually guaranteed to be unsigned int? does specifications actually dictate that, or did the compiler developers just chose to implement it like that?) --- main/streams/plain_wrapper.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main/streams/plain_wrapper.c b/main/streams/plain_wrapper.c index 467a7361895e6..538aecb92db12 100644 --- a/main/streams/plain_wrapper.c +++ b/main/streams/plain_wrapper.c @@ -358,7 +358,7 @@ static ssize_t php_stdiop_write(php_stream *stream, const char *buf, size_t coun if (ZEND_SIZE_T_UINT_OVFL(count)) { count = UINT_MAX; } - bytes_written = _write(data->fd, buf, (unsigned int)((count > UINT_MAX) ? UINT_MAX : count)); + bytes_written = _write(data->fd, buf, PLAIN_WRAP_BUF_SIZE(count)); #else ssize_t bytes_written = write(data->fd, buf, count); #endif From 3e63d6aa6abd9a7c6f7eeeb65b9558bd2a441b9f Mon Sep 17 00:00:00 2001 From: divinity76 Date: Wed, 24 Jan 2024 00:08:59 +0100 Subject: [PATCH 06/18] use int_max... --- main/streams/plain_wrapper.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/main/streams/plain_wrapper.c b/main/streams/plain_wrapper.c index 538aecb92db12..3fa164adf4464 100644 --- a/main/streams/plain_wrapper.c +++ b/main/streams/plain_wrapper.c @@ -355,10 +355,7 @@ static ssize_t php_stdiop_write(php_stream *stream, const char *buf, size_t coun if (data->fd >= 0) { #ifdef PHP_WIN32 ssize_t bytes_written; - if (ZEND_SIZE_T_UINT_OVFL(count)) { - count = UINT_MAX; - } - bytes_written = _write(data->fd, buf, PLAIN_WRAP_BUF_SIZE(count)); + bytes_written = _write(data->fd, buf, (int)(count > INT_MAX ? INT_MAX : count)); #else ssize_t bytes_written = write(data->fd, buf, count); #endif From 2f9171a04304a3c30e6e39d9d1835d4b60b76d98 Mon Sep 17 00:00:00 2001 From: divinity76 Date: Wed, 24 Jan 2024 00:14:46 +0100 Subject: [PATCH 07/18] nitpick --- main/streams/plain_wrapper.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main/streams/plain_wrapper.c b/main/streams/plain_wrapper.c index 3fa164adf4464..db2a41d7f9446 100644 --- a/main/streams/plain_wrapper.c +++ b/main/streams/plain_wrapper.c @@ -355,7 +355,7 @@ static ssize_t php_stdiop_write(php_stream *stream, const char *buf, size_t coun if (data->fd >= 0) { #ifdef PHP_WIN32 ssize_t bytes_written; - bytes_written = _write(data->fd, buf, (int)(count > INT_MAX ? INT_MAX : count)); + bytes_written = _write(data->fd, buf, (unsigned int)(count > INT_MAX ? INT_MAX : count)); #else ssize_t bytes_written = write(data->fd, buf, count); #endif From d549b121cfd3702fa5295e5dd5d30464a6f8cf22 Mon Sep 17 00:00:00 2001 From: divinity76 Date: Mon, 29 Jan 2024 20:09:57 +0100 Subject: [PATCH 08/18] pr nitpick --- main/streams/plain_wrapper.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/main/streams/plain_wrapper.c b/main/streams/plain_wrapper.c index db2a41d7f9446..b667876b94ab7 100644 --- a/main/streams/plain_wrapper.c +++ b/main/streams/plain_wrapper.c @@ -354,8 +354,7 @@ static ssize_t php_stdiop_write(php_stream *stream, const char *buf, size_t coun if (data->fd >= 0) { #ifdef PHP_WIN32 - ssize_t bytes_written; - bytes_written = _write(data->fd, buf, (unsigned int)(count > INT_MAX ? INT_MAX : count)); + ssize_t bytes_written = _write(data->fd, buf, (unsigned int)(count > INT_MAX ? INT_MAX : count)); #else ssize_t bytes_written = write(data->fd, buf, count); #endif From 191f1c3ada27a5b1077b1c9130bc8c1ebf8a0f57 Mon Sep 17 00:00:00 2001 From: divinity76 Date: Mon, 29 Jan 2024 20:16:30 +0100 Subject: [PATCH 09/18] dont use tmpfile (per codereview) --- .../tests/file/file_put_contents_5gb.phpt | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/ext/standard/tests/file/file_put_contents_5gb.phpt b/ext/standard/tests/file/file_put_contents_5gb.phpt index 0b29be1803602..3bd98d633970e 100644 --- a/ext/standard/tests/file/file_put_contents_5gb.phpt +++ b/ext/standard/tests/file/file_put_contents_5gb.phpt @@ -27,26 +27,29 @@ function get_system_memory(): int|float|false if (get_system_memory() < 10 * 1024 * 1024 * 1024) { die('skip Reason: Insufficient RAM (less than 10GB)'); } -$tmpfileh = tmpfile(); +$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'); } -$tmpfile = stream_get_meta_data($tmpfileh)['uri']; +fclose($tmpfileh); +unlink($tmpfile); if (disk_free_space(dirname($tmpfile)) < 10 * 1024 * 1024 * 1024) { die('skip Reason: Insufficient disk space (less than 10GB)'); } -fclose($tmpfileh); ?> --INI-- memory_limit=6G - +--CLEAN-- + --FILE-- --EXPECT-- From 7a8d13a52109022805d091031c2813d328abbb71 Mon Sep 17 00:00:00 2001 From: divinity76 Date: Wed, 7 Feb 2024 20:19:10 +0100 Subject: [PATCH 10/18] Update file_put_contents_5gb.phpt --- ext/standard/tests/file/file_put_contents_5gb.phpt | 3 --- 1 file changed, 3 deletions(-) diff --git a/ext/standard/tests/file/file_put_contents_5gb.phpt b/ext/standard/tests/file/file_put_contents_5gb.phpt index 3bd98d633970e..c269f811930fc 100644 --- a/ext/standard/tests/file/file_put_contents_5gb.phpt +++ b/ext/standard/tests/file/file_put_contents_5gb.phpt @@ -37,9 +37,7 @@ 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 --CLEAN-- @@ -60,6 +58,5 @@ if ($result !== strlen($large_string)) { echo "File written successfully."; } ?> - --EXPECT-- File written successfully. From d45845b4896e3489f5ae61c5730e9f67e673b3cc Mon Sep 17 00:00:00 2001 From: divinity76 Date: Wed, 7 Feb 2024 20:19:42 +0100 Subject: [PATCH 11/18] Update plain_wrapper.c --- main/streams/plain_wrapper.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main/streams/plain_wrapper.c b/main/streams/plain_wrapper.c index b667876b94ab7..b1d0f00f4b1fa 100644 --- a/main/streams/plain_wrapper.c +++ b/main/streams/plain_wrapper.c @@ -40,7 +40,7 @@ # include "win32/time.h" # include "win32/ioutil.h" # include "win32/readdir.h" -#include +# include #endif #define php_stream_fopen_from_fd_int(fd, mode, persistent_id) _php_stream_fopen_from_fd_int((fd), (mode), (persistent_id) STREAMS_CC) From 04963c5fb6a4576cd4fd3c927f1534aae9cd3f9b Mon Sep 17 00:00:00 2001 From: divinity76 Date: Fri, 9 Feb 2024 16:57:56 +0100 Subject: [PATCH 12/18] Update file_put_contents_5gb.phpt --- ext/standard/tests/file/file_put_contents_5gb.phpt | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/ext/standard/tests/file/file_put_contents_5gb.phpt b/ext/standard/tests/file/file_put_contents_5gb.phpt index c269f811930fc..d5da3dda6d165 100644 --- a/ext/standard/tests/file/file_put_contents_5gb.phpt +++ b/ext/standard/tests/file/file_put_contents_5gb.phpt @@ -5,7 +5,6 @@ Test file_put_contents() function with 5GB string if (getenv('SKIP_SLOW_TESTS')) { die('skip slow test'); } - function get_system_memory(): int|float|false { if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') { @@ -40,16 +39,10 @@ if (disk_free_space(dirname($tmpfile)) < 10 * 1024 * 1024 * 1024) { ?> --INI-- memory_limit=6G ---CLEAN-- - --FILE-- +--CLEAN-- + --EXPECT-- File written successfully. From 59198f36f1f47dcb69c60efeb5c353f33031e2b2 Mon Sep 17 00:00:00 2001 From: divinity76 Date: Thu, 22 Feb 2024 18:13:58 +0100 Subject: [PATCH 13/18] Update ext/standard/tests/file/file_put_contents_5gb.phpt Co-authored-by: Jakub Zelenka --- ext/standard/tests/file/file_put_contents_5gb.phpt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/standard/tests/file/file_put_contents_5gb.phpt b/ext/standard/tests/file/file_put_contents_5gb.phpt index d5da3dda6d165..157c261c05b10 100644 --- a/ext/standard/tests/file/file_put_contents_5gb.phpt +++ b/ext/standard/tests/file/file_put_contents_5gb.phpt @@ -23,7 +23,7 @@ function get_system_memory(): int|float|false } return false; } -if (get_system_memory() < 10 * 1024 * 1024 * 1024) { +if (get_system_memory() < 10 * 1024 * 1024) { die('skip Reason: Insufficient RAM (less than 10GB)'); } $tmpfile = sys_get_temp_dir() . DIRECTORY_SEPARATOR . "test_file_put_contents_5gb.bin"; From 3a259fbd2597192db57e5a3ea474fbeaa2b32b09 Mon Sep 17 00:00:00 2001 From: divinity76 Date: Thu, 22 Feb 2024 18:21:19 +0100 Subject: [PATCH 14/18] Update ext/standard/tests/file/file_put_contents_5gb.phpt --- ext/standard/tests/file/file_put_contents_5gb.phpt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ext/standard/tests/file/file_put_contents_5gb.phpt b/ext/standard/tests/file/file_put_contents_5gb.phpt index 157c261c05b10..e89547eee1ad5 100644 --- a/ext/standard/tests/file/file_put_contents_5gb.phpt +++ b/ext/standard/tests/file/file_put_contents_5gb.phpt @@ -50,6 +50,10 @@ if ($result !== strlen($large_string)) { } else { echo "File written successfully."; } +clearstatcache(true, $tmpfile); +if(file_exists($tmpfile)) { + unlink($tmpfile); +} ?> --CLEAN-- Date: Thu, 22 Feb 2024 22:21:32 +0100 Subject: [PATCH 15/18] consistently return bytes --- ext/standard/tests/file/file_put_contents_5gb.phpt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ext/standard/tests/file/file_put_contents_5gb.phpt b/ext/standard/tests/file/file_put_contents_5gb.phpt index e89547eee1ad5..b53cb0f522235 100644 --- a/ext/standard/tests/file/file_put_contents_5gb.phpt +++ b/ext/standard/tests/file/file_put_contents_5gb.phpt @@ -11,7 +11,7 @@ function get_system_memory(): int|float|false // Windows-based memory check @exec('wmic OS get FreePhysicalMemory', $output); if (isset($output[1])) { - return (int)trim($output[1]); + return ((int)trim($output[1])) * 1024; } } else { // Unix/Linux-based memory check @@ -23,7 +23,7 @@ function get_system_memory(): int|float|false } return false; } -if (get_system_memory() < 10 * 1024 * 1024) { +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"; From d3fc6022ccda9bcaf664600dc4f9d7c73be12b9d Mon Sep 17 00:00:00 2001 From: divinity76 Date: Fri, 23 Feb 2024 13:36:04 +0100 Subject: [PATCH 16/18] skip <40bit systems --- ext/standard/tests/file/file_put_contents_5gb.phpt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ext/standard/tests/file/file_put_contents_5gb.phpt b/ext/standard/tests/file/file_put_contents_5gb.phpt index b53cb0f522235..b45cba43b5129 100644 --- a/ext/standard/tests/file/file_put_contents_5gb.phpt +++ b/ext/standard/tests/file/file_put_contents_5gb.phpt @@ -2,6 +2,10 @@ Test file_put_contents() function with 5GB string --SKIPIF-- Date: Fri, 23 Feb 2024 13:45:22 +0100 Subject: [PATCH 17/18] Update ext/standard/tests/file/file_put_contents_5gb.phpt --- ext/standard/tests/file/file_put_contents_5gb.phpt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/standard/tests/file/file_put_contents_5gb.phpt b/ext/standard/tests/file/file_put_contents_5gb.phpt index b45cba43b5129..eaaa4b00f28d2 100644 --- a/ext/standard/tests/file/file_put_contents_5gb.phpt +++ b/ext/standard/tests/file/file_put_contents_5gb.phpt @@ -55,7 +55,7 @@ if ($result !== strlen($large_string)) { echo "File written successfully."; } clearstatcache(true, $tmpfile); -if(file_exists($tmpfile)) { +if (file_exists($tmpfile)) { unlink($tmpfile); } ?> From 3ff36f66efb0db78c97ee67b29aa37c6569cf841 Mon Sep 17 00:00:00 2001 From: divinity76 Date: Fri, 23 Feb 2024 17:13:36 +0100 Subject: [PATCH 18/18] Update ext/standard/tests/file/file_put_contents_5gb.phpt Co-authored-by: Saki Takamachi <34942839+SakiTakamachi@users.noreply.github.com> --- ext/standard/tests/file/file_put_contents_5gb.phpt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/standard/tests/file/file_put_contents_5gb.phpt b/ext/standard/tests/file/file_put_contents_5gb.phpt index eaaa4b00f28d2..7d91ef691b586 100644 --- a/ext/standard/tests/file/file_put_contents_5gb.phpt +++ b/ext/standard/tests/file/file_put_contents_5gb.phpt @@ -55,7 +55,7 @@ if ($result !== strlen($large_string)) { echo "File written successfully."; } clearstatcache(true, $tmpfile); -if (file_exists($tmpfile)) { +if (file_exists($tmpfile)) { unlink($tmpfile); } ?>