FULL PRODUCT VERSION :
java version "1.6.0_17"
Java(TM) SE Runtime Environment (build 1.6.0_17-b04)
Java HotSpot(TM) Client VM (build 14.3-b01, mixed mode, sharing)
ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows XP [Version 5.1.2600]
A DESCRIPTION OF THE PROBLEM :
File: j2se/src/windows/native/java/io/io_util_md.c
Function: handleAvailable()
This piece of code apperas to have issues:
long highPos = 0;
DWORD sizeLow = 0;
DWORD sizeHigh = 0;
DWORD lowPos = SetFilePointer(h, 0, &highPos, FILE_CURRENT);
if (lowPos == ((DWORD)-1)) {
return FALSE;
}
current = (((jlong)highPos) << 32) | lowPos;
end = GetFileSize(h, &sizeHigh);
if (sizeLow == ((DWORD)-1)) {
return FALSE;
}
The if() after SetFilePointer() should check GetLastError() because lowPos can be 0xffffffff if the file is positioned at 4GB-1.
sizeLow is always zero, yet it is compared with -1.
The sizeLow comparison should also check GetLastError().
sizeHigh is ignored, which breaks available() for files greater than 4 GB.
Something like this should be better:
long highPos = 0;
DWORD sizeLow = 0;
DWORD sizeHigh = 0;
DWORD lowPos = SetFilePointer(h, 0, &highPos, FILE_CURRENT);
if (lowPos == ((DWORD)-1) && GetLastError() != NO_ERROR) {
return FALSE;
}
current = (((jlong)highPos) << 32) | lowPos;
sizeLow = GetFileSize(h, &sizeHigh);
if (sizeLow == ((DWORD)-1) && GetLastError() != NO_ERROR) {
return FALSE;
}
end = (((jlong)sizeHigh) << 32) | sizeLow;
Code audit: check that GetLastError() is used wherever SetFilePointer() or GetFileSize() is used. Or maybe write wrappers for SetFilePointer() and GetFileSize() that do the checking and combining and return a jlong.
See also: http://forums.sun.com/thread.jspa?threadID=5419253
REPRODUCIBILITY :
This bug can be reproduced always.
java version "1.6.0_17"
Java(TM) SE Runtime Environment (build 1.6.0_17-b04)
Java HotSpot(TM) Client VM (build 14.3-b01, mixed mode, sharing)
ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows XP [Version 5.1.2600]
A DESCRIPTION OF THE PROBLEM :
File: j2se/src/windows/native/java/io/io_util_md.c
Function: handleAvailable()
This piece of code apperas to have issues:
long highPos = 0;
DWORD sizeLow = 0;
DWORD sizeHigh = 0;
DWORD lowPos = SetFilePointer(h, 0, &highPos, FILE_CURRENT);
if (lowPos == ((DWORD)-1)) {
return FALSE;
}
current = (((jlong)highPos) << 32) | lowPos;
end = GetFileSize(h, &sizeHigh);
if (sizeLow == ((DWORD)-1)) {
return FALSE;
}
The if() after SetFilePointer() should check GetLastError() because lowPos can be 0xffffffff if the file is positioned at 4GB-1.
sizeLow is always zero, yet it is compared with -1.
The sizeLow comparison should also check GetLastError().
sizeHigh is ignored, which breaks available() for files greater than 4 GB.
Something like this should be better:
long highPos = 0;
DWORD sizeLow = 0;
DWORD sizeHigh = 0;
DWORD lowPos = SetFilePointer(h, 0, &highPos, FILE_CURRENT);
if (lowPos == ((DWORD)-1) && GetLastError() != NO_ERROR) {
return FALSE;
}
current = (((jlong)highPos) << 32) | lowPos;
sizeLow = GetFileSize(h, &sizeHigh);
if (sizeLow == ((DWORD)-1) && GetLastError() != NO_ERROR) {
return FALSE;
}
end = (((jlong)sizeHigh) << 32) | sizeLow;
Code audit: check that GetLastError() is used wherever SetFilePointer() or GetFileSize() is used. Or maybe write wrappers for SetFilePointer() and GetFileSize() that do the checking and combining and return a jlong.
See also: http://forums.sun.com/thread.jspa?threadID=5419253
REPRODUCIBILITY :
This bug can be reproduced always.