diff options
-rw-r--r-- | ext/standard/tests/file/ftruncate_bug76422.phpt | 36 | ||||
-rw-r--r-- | ext/standard/tests/file/ftruncate_variation2-win32.phpt | 12 | ||||
-rw-r--r-- | main/streams/plain_wrapper.c | 22 |
3 files changed, 64 insertions, 6 deletions
diff --git a/ext/standard/tests/file/ftruncate_bug76422.phpt b/ext/standard/tests/file/ftruncate_bug76422.phpt new file mode 100644 index 0000000000..46f52aace9 --- /dev/null +++ b/ext/standard/tests/file/ftruncate_bug76422.phpt @@ -0,0 +1,36 @@ +--TEST--
+Bug #76422 ftruncate fails on files > 2GB
+--SKIPIF--
+<?php
+if (PHP_INT_SIZE < 8) {
+ die('skip.. only valid for 64-bit');
+}
+?>
+--FILE--
+<?php
+
+$fn = dirname(__FILE__) . DIRECTORY_SEPARATOR . "test76422";
+
+$file_handle = fopen($fn,'cb');
+
+if (false === $file_handle) {
+ die('Cannot open test file :/');
+}
+
+$truncate_offset = 4 * 1024 * 1024 * 1024 + 1;
+$ftruncate_result = ftruncate($file_handle, $truncate_offset);
+
+if (false === $ftruncate_result) {
+ die('Truncate has failed :/');
+}
+
+fclose($file_handle);
+var_dump(filesize($fn) >= $truncate_offset);
+?>
+--CLEAN--
+<?php
+$fn = dirname(__FILE__) . "/test76422";
+unlink($fn);
+?>
+--EXPECT--
+bool(true)
diff --git a/ext/standard/tests/file/ftruncate_variation2-win32.phpt b/ext/standard/tests/file/ftruncate_variation2-win32.phpt index 535881206a..6d62f75f1a 100644 --- a/ext/standard/tests/file/ftruncate_variation2-win32.phpt +++ b/ext/standard/tests/file/ftruncate_variation2-win32.phpt @@ -77,7 +77,7 @@ echo "Done\n"; -- Testing ftruncate(): truncate file to size = current size -- int(1024) int(0) -bool(true) +bool(false) int(0) bool(false) int(1024) @@ -85,7 +85,7 @@ int(1024) -- Testing ftruncate(): truncate file to size = current size -- int(1024) int(0) -bool(true) +bool(false) int(0) bool(false) int(1024) @@ -93,7 +93,7 @@ int(1024) -- Testing ftruncate(): truncate file to size = current size -- int(1024) int(0) -bool(true) +bool(false) int(0) bool(false) int(1024) @@ -271,7 +271,7 @@ int(1024) -- Testing ftruncate(): truncate file to size = current size -- int(1024) int(0) -bool(true) +bool(false) int(0) bool(false) int(1024) @@ -279,7 +279,7 @@ int(1024) -- Testing ftruncate(): truncate file to size = current size -- int(1024) int(0) -bool(true) +bool(false) int(0) bool(false) int(1024) @@ -287,7 +287,7 @@ int(1024) -- Testing ftruncate(): truncate file to size = current size -- int(1024) int(0) -bool(true) +bool(false) int(0) bool(false) int(1024) diff --git a/main/streams/plain_wrapper.c b/main/streams/plain_wrapper.c index 7657b35faf..285b12b052 100644 --- a/main/streams/plain_wrapper.c +++ b/main/streams/plain_wrapper.c @@ -854,7 +854,29 @@ static int php_stdiop_set_option(php_stream *stream, int option, int value, void if (new_size < 0) { return PHP_STREAM_OPTION_RETURN_ERR; } +#ifdef PHP_WIN32 + HANDLE h = (HANDLE) _get_osfhandle(fd); + if (INVALID_HANDLE_VALUE == h) { + return PHP_STREAM_OPTION_RETURN_ERR; + } + LARGE_INTEGER sz; +#if defined(_WIN64) + sz.HighPart = (new_size >> 32); + sz.LowPart = (new_size & 0xffffffff); +#else + sz.HighPart = 0; + sz.LowPart = new_size; +#endif + if (INVALID_SET_FILE_POINTER == SetFilePointerEx(h, sz, NULL, FILE_BEGIN) && NO_ERROR != GetLastError()) { + return PHP_STREAM_OPTION_RETURN_ERR; + } + if (0 == SetEndOfFile(h)) { + return PHP_STREAM_OPTION_RETURN_ERR; + } + return PHP_STREAM_OPTION_RETURN_OK; +#else return ftruncate(fd, new_size) == 0 ? PHP_STREAM_OPTION_RETURN_OK : PHP_STREAM_OPTION_RETURN_ERR; +#endif } } |