From 446c09dd3383f6f64387807db541a6620b522ffe Mon Sep 17 00:00:00 2001 From: Brian Haar Date: Wed, 14 Sep 2011 11:50:56 -0600 Subject: [PATCH] Fix for File.length() integer overflow on 32-bit Windows. The File.length() method was returning a signed 32-bit value on 32-bit Windows systems. This was causing an integer overflow on file sizes greater than 2 GB. This appears to be caused by the way Windows handles the STAT() function. This patch checks whether the current platform is Windows then uses the Windows API to get the correct file size and return it as a jlong. --- classpath/java-io.cpp | 33 +++++++++++++++++++++++++-------- 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/classpath/java-io.cpp b/classpath/java-io.cpp index 9bcfa88afd..d0165019d6 100644 --- a/classpath/java-io.cpp +++ b/classpath/java-io.cpp @@ -342,15 +342,32 @@ Java_java_io_File_toAbsolutePath(JNIEnv* e UNUSED, jclass, jstring path) extern "C" JNIEXPORT jlong JNICALL Java_java_io_File_length(JNIEnv* e, jclass, jstring path) { - string_t chars = getChars(e, path); - if (chars) { - STRUCT_STAT s; - int r = STAT(chars, &s); - releaseChars(e, path, chars); - if (r == 0) { - return s.st_size; + + #ifdef PLATFORM_WINDOWS + + LARGE_INTEGER fileSize; + HANDLE file = CreateFileW((wchar_t *)e->GetStringChars(path, 0), FILE_READ_DATA, FILE_SHARE_READ, 0, + OPEN_EXISTING, 0, 0); + e->ReleaseStringChars(path, 0); + if (file != INVALID_HANDLE_VALUE) + GetFileSizeEx(file, &fileSize); + else return -1; + CloseHandle(file); + return (jlong)fileSize.QuadPart; + + #else + + string_t chars = getChars(e, path); + if (chars) { + STRUCT_STAT s; + int r = STAT(chars, &s); + releaseChars(e, path, chars); + if (r == 0) { + return s.st_size; + } } - } + + #endif return 0; }