From 030f5abde1bcdc0f20c4614d70f03d6dcb21e555 Mon Sep 17 00:00:00 2001 From: kiler129 Date: Wed, 4 Jun 2025 00:11:00 -0500 Subject: [PATCH] Fix GH-18753: file_get_contents() and file_put_contents() fail with data >=2GB on macOS & BSD --- ext/standard/tests/file/gh18753.phpt | 29 ++++++++++++++++++++++++++++ main/streams/plain_wrapper.c | 10 +++++++--- 2 files changed, 36 insertions(+), 3 deletions(-) create mode 100644 ext/standard/tests/file/gh18753.phpt diff --git a/ext/standard/tests/file/gh18753.phpt b/ext/standard/tests/file/gh18753.phpt new file mode 100644 index 0000000000000..a5bc8b8b7c680 --- /dev/null +++ b/ext/standard/tests/file/gh18753.phpt @@ -0,0 +1,29 @@ +--TEST-- +GH-18753 (file_get_contents() and file_put_contents() fail with data >=2GB on macOS & BSD) +--CREDITS-- +Gregory House +--INI-- +memory_limit=-1 +--SKIPIF-- + +--FILE-- + +--CLEAN-- + +--EXPECT-- +-- file_put_contents() -- +2147483648 +-- file_get_contents() -- +2147483648 diff --git a/main/streams/plain_wrapper.c b/main/streams/plain_wrapper.c index 1d5b7cfdac40d..8bbea2faa0df0 100644 --- a/main/streams/plain_wrapper.c +++ b/main/streams/plain_wrapper.c @@ -53,12 +53,16 @@ extern int php_get_uid_by_name(const char *name, uid_t *uid); extern int php_get_gid_by_name(const char *name, gid_t *gid); #endif -#if defined(PHP_WIN32) +#if defined(PHP_WIN32) || defined(__APPLE__) || defined(__MACH__) || defined(BSD) || defined(__DragonFly__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) # define PLAIN_WRAP_BUF_SIZE(st) ((unsigned int)(st > INT_MAX ? INT_MAX : st)) +#else +# define PLAIN_WRAP_BUF_SIZE(st) (st) +#endif + +#if defined(PHP_WIN32) #define fsync _commit #define fdatasync fsync #else -# define PLAIN_WRAP_BUF_SIZE(st) (st) # if !defined(HAVE_FDATASYNC) # define fdatasync fsync # elif defined(__APPLE__) @@ -357,7 +361,7 @@ static ssize_t php_stdiop_write(php_stream *stream, const char *buf, size_t coun #ifdef PHP_WIN32 bytes_written = _write(data->fd, buf, PLAIN_WRAP_BUF_SIZE(count)); #else - bytes_written = write(data->fd, buf, count); + bytes_written = write(data->fd, buf, PLAIN_WRAP_BUF_SIZE(count)); #endif if (bytes_written < 0) { if (PHP_IS_TRANSIENT_ERROR(errno)) {