A DESCRIPTION OF THE PROBLEM :
For very long strings of length greater than Integer.MAX_VALUE / 3 DataOutputStream.writeUTF might not behave as expected, if the byte length of the UTF encoding exceeds Integer.MAX_VALUE. In this case the internal variable "utflen" overflows and becomes negative such that this case is not caught by the if case (utflen > 65535). As a result the method might end up in an ArrayIndexOutOfBoundsException or a NegativeArraySizeException. However, the expected exception in this case would be an UTFDataFormatException.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
The issue can be reproduced using the two attached unit tests.
---------- BEGIN SOURCE ----------
@Test
public void testArrayIndexOutOfBoundsException() throws IOException {
int size = Integer.MAX_VALUE / 3 + 1;
StringBuilder sb = new StringBuilder(size);
char c = 0x0800; // this character gives 3 bytes when encoded using UTF-8
for (int i = 0; i < size; ++i) {
sb.append(c);
}
ByteArrayOutputStream bos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(bos);
String s = sb.toString();
dos.writeUTF(s); //throws ArrayIndexOutOfBoundsException instead of expected UTFDataFormatException
}
@Test
public void testNegativeArraySizeException() throws IOException {
int size = Integer.MAX_VALUE / 2 + 1;
StringBuilder sb = new StringBuilder(size);
char c = 0x0800; // this character gives 3 bytes when encoded using UTF-8
for (int i = 0; i < size; ++i) {
sb.append(c);
}
ByteArrayOutputStream bos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(bos);
String s = sb.toString();
dos.writeUTF(s); //throws NegativeArraySizeException instead of expected UTFDataFormatException
}
---------- END SOURCE ----------
For very long strings of length greater than Integer.MAX_VALUE / 3 DataOutputStream.writeUTF might not behave as expected, if the byte length of the UTF encoding exceeds Integer.MAX_VALUE. In this case the internal variable "utflen" overflows and becomes negative such that this case is not caught by the if case (utflen > 65535). As a result the method might end up in an ArrayIndexOutOfBoundsException or a NegativeArraySizeException. However, the expected exception in this case would be an UTFDataFormatException.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
The issue can be reproduced using the two attached unit tests.
---------- BEGIN SOURCE ----------
@Test
public void testArrayIndexOutOfBoundsException() throws IOException {
int size = Integer.MAX_VALUE / 3 + 1;
StringBuilder sb = new StringBuilder(size);
char c = 0x0800; // this character gives 3 bytes when encoded using UTF-8
for (int i = 0; i < size; ++i) {
sb.append(c);
}
ByteArrayOutputStream bos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(bos);
String s = sb.toString();
dos.writeUTF(s); //throws ArrayIndexOutOfBoundsException instead of expected UTFDataFormatException
}
@Test
public void testNegativeArraySizeException() throws IOException {
int size = Integer.MAX_VALUE / 2 + 1;
StringBuilder sb = new StringBuilder(size);
char c = 0x0800; // this character gives 3 bytes when encoded using UTF-8
for (int i = 0; i < size; ++i) {
sb.append(c);
}
ByteArrayOutputStream bos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(bos);
String s = sb.toString();
dos.writeUTF(s); //throws NegativeArraySizeException instead of expected UTFDataFormatException
}
---------- END SOURCE ----------
- csr for
-
JDK-8221428 DataOutputStream.writeUTF may throw unexpected exceptions
- Closed
- duplicates
-
JDK-4296707 (spec) DataOutputStream javadoc is incomplete (e.g limit on strings size)
- Closed
- relates to
-
JDK-8219409 Clarify capacity of StringBuffer/StringBuilder near Integer.MAX_VALUE
- Open
-
JDK-8221568 DataOutputStream/WriteUTF.java fails due to "OutOfMemoryError: Java heap space"
- Resolved
- links to