-
Bug
-
Resolution: Duplicate
-
P3
-
None
-
1.1.4
-
sparc
-
solaris_2.5.1
Problem:
*** We need to test for len < 0 then throw ArrayIndexOutOfBoundsException ***
*** We need to test for off+len > datalen then throw ArrayIndexOutOfBoundsException ***
The Java Specification Language: Reference 22.3.3
public int read(byte[] b, int off, int len)
throws IOException, NullPointerException,
IndexOutOfBoundsException
If off is negative, or len is negative, or off+len is greater than the length of the array b, then an
IndexOutOfBoundsException is thrown.
JAVA CODE for read calls native readBytes
JAVA WORKSPACE TREE: /src/share/java/lang
File: io.c
Sections of code in question:
*** java_io_FileInputStream_readBytes(Hjava_io_FileInputStream *this, HArrayOfByte *data, long off, long len)
*** java_io_RandomAccessFile_readBytes(Hjava_io_RandomAccessFile *this, HArrayOfByte *data, long off, long len)
Code snippet:
dataptr = unhand(data)->body;
datalen = obj_length(data);
*** We need to test for below description in FileInputStream + RandomAccessFile native code for readBytes ***
DESCRIPTION OF PROBLEM:
*** We need to test for len < 0 then throw ArrayIndexOutOfBoundsException ***
*** We need to test for off+len > datalen then throw ArrayIndexOutOfBoundsException ***
*** Could use code: if ((off < 0) || (len < 0)|| ( off + len > datalen)||(off > datalen)) { ***
*** Use above line instead of below line ***
if ((off < 0) || (off > datalen)) { *** Does not check all cases for throwing exceptions
SignalError(0, JAVAPKG "ArrayIndexOutOfBoundsException", 0);
return -1;
}
********************************************************
*** This should be covered above and throw exception ***
if (off + len > datalen) {
len = datalen - off;
}
********************************************************
********************************************************
*** Change the len <= 0 to len = 0 the return zero ***
if (len <= 0) {
return 0;
}
********************************************************
n = sysReadFD(fdptr, dataptr + off, len);
if (n == -1) {
SignalError(0, IO_EXCEPTION, "read error");
}
/* AVH: this is bogus but it stops the pointer from being gc'd */
KEEP_POINTER_ALIVE(dataptr);
return (n == 0) ? -1 : n;
*******************************************************************************************
How to reproduce bug:
Use below test to test against errors:
change (off) and (len) values described below.
off=0 len=5 buf.size=5 This will test if we can read array size that matches off+len
off=1 len=5 buf.size=5 This will test if off+len is greater than buf.size then throw exception
off=-1 len=5 buf.size=5 This will test if off is negative then throw exception
off=1 len=-5 buf.size=5 This will test if len is negative then throw exception
off=6 len=1 buf.size=5 This will test if off is greater than buf.size then throw exception
Test Code:
import java.io.*;
public class readbytes_test {
public static void main(String argv[]) {
try {
byte buf[] = new byte[5];
int off = 0;
int len = 5;
// Tests that need to be run
// off=0 len=5 buf.size=5 This will test if we can read array size that matches off+len
// off=1 len=5 buf.size=5 This will test if off+len is greater than buf.size then throw exception
// off=-1 len=5 buf.size=5 This will test if off is negative then throw exception
// off=1 len=-5 buf.size=5 This will test if len is negative then throw exception
// off=6 len=1 buf.size=5 This will test if off is greater than buf.size then throw exception
// Test for FileInputStream (read) Method which calls native readBytes
FileInputStream f = new FileInputStream("./test.txt");
System.out.println("Array.length = "+buf.length);
System.out.println("Bytes Read: " + f.read(buf, off, len));
// Loops through array and prints out buffer values
for (int i = 0; i < buf.length; i++){
System.out.println("buffer["+i+"] value = " + buf[i]);
}
// Test for RandomAccessFile (read) Method which calls native readBytes
RandomAccessFile raf = new RandomAccessFile("./test.txt", "r");
System.out.println("Array.length = "+buf.length);
System.out.println("Bytes Read: " + f.read(buf, off, len));
// Loops through array and prints out buffer values
for (int i = 0; i < buf.length; i++){
System.out.println("buf["+i+"] = " + buf[i]);
}
}
catch (Exception x) {
x.printStackTrace();
}
}
}
*** We need to test for len < 0 then throw ArrayIndexOutOfBoundsException ***
*** We need to test for off+len > datalen then throw ArrayIndexOutOfBoundsException ***
The Java Specification Language: Reference 22.3.3
public int read(byte[] b, int off, int len)
throws IOException, NullPointerException,
IndexOutOfBoundsException
If off is negative, or len is negative, or off+len is greater than the length of the array b, then an
IndexOutOfBoundsException is thrown.
JAVA CODE for read calls native readBytes
JAVA WORKSPACE TREE: /src/share/java/lang
File: io.c
Sections of code in question:
*** java_io_FileInputStream_readBytes(Hjava_io_FileInputStream *this, HArrayOfByte *data, long off, long len)
*** java_io_RandomAccessFile_readBytes(Hjava_io_RandomAccessFile *this, HArrayOfByte *data, long off, long len)
Code snippet:
dataptr = unhand(data)->body;
datalen = obj_length(data);
*** We need to test for below description in FileInputStream + RandomAccessFile native code for readBytes ***
DESCRIPTION OF PROBLEM:
*** We need to test for len < 0 then throw ArrayIndexOutOfBoundsException ***
*** We need to test for off+len > datalen then throw ArrayIndexOutOfBoundsException ***
*** Could use code: if ((off < 0) || (len < 0)|| ( off + len > datalen)||(off > datalen)) { ***
*** Use above line instead of below line ***
if ((off < 0) || (off > datalen)) { *** Does not check all cases for throwing exceptions
SignalError(0, JAVAPKG "ArrayIndexOutOfBoundsException", 0);
return -1;
}
********************************************************
*** This should be covered above and throw exception ***
if (off + len > datalen) {
len = datalen - off;
}
********************************************************
********************************************************
*** Change the len <= 0 to len = 0 the return zero ***
if (len <= 0) {
return 0;
}
********************************************************
n = sysReadFD(fdptr, dataptr + off, len);
if (n == -1) {
SignalError(0, IO_EXCEPTION, "read error");
}
/* AVH: this is bogus but it stops the pointer from being gc'd */
KEEP_POINTER_ALIVE(dataptr);
return (n == 0) ? -1 : n;
*******************************************************************************************
How to reproduce bug:
Use below test to test against errors:
change (off) and (len) values described below.
off=0 len=5 buf.size=5 This will test if we can read array size that matches off+len
off=1 len=5 buf.size=5 This will test if off+len is greater than buf.size then throw exception
off=-1 len=5 buf.size=5 This will test if off is negative then throw exception
off=1 len=-5 buf.size=5 This will test if len is negative then throw exception
off=6 len=1 buf.size=5 This will test if off is greater than buf.size then throw exception
Test Code:
import java.io.*;
public class readbytes_test {
public static void main(String argv[]) {
try {
byte buf[] = new byte[5];
int off = 0;
int len = 5;
// Tests that need to be run
// off=0 len=5 buf.size=5 This will test if we can read array size that matches off+len
// off=1 len=5 buf.size=5 This will test if off+len is greater than buf.size then throw exception
// off=-1 len=5 buf.size=5 This will test if off is negative then throw exception
// off=1 len=-5 buf.size=5 This will test if len is negative then throw exception
// off=6 len=1 buf.size=5 This will test if off is greater than buf.size then throw exception
// Test for FileInputStream (read) Method which calls native readBytes
FileInputStream f = new FileInputStream("./test.txt");
System.out.println("Array.length = "+buf.length);
System.out.println("Bytes Read: " + f.read(buf, off, len));
// Loops through array and prints out buffer values
for (int i = 0; i < buf.length; i++){
System.out.println("buffer["+i+"] value = " + buf[i]);
}
// Test for RandomAccessFile (read) Method which calls native readBytes
RandomAccessFile raf = new RandomAccessFile("./test.txt", "r");
System.out.println("Array.length = "+buf.length);
System.out.println("Bytes Read: " + f.read(buf, off, len));
// Loops through array and prints out buffer values
for (int i = 0; i < buf.length; i++){
System.out.println("buf["+i+"] = " + buf[i]);
}
}
catch (Exception x) {
x.printStackTrace();
}
}
}
- duplicates
-
JDK-4017728 runtime/io.c: read on byte array doesn't throw required exception if start index
- Closed