JDK-8188099 : (str) NegativeArraySizeException in String.getBytes()
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.lang
  • Affected Version: 9
  • Priority: P4
  • Status: Open
  • Resolution: Unresolved
  • OS: linux
  • CPU: x86_64
  • Submitted: 2017-09-27
  • Updated: 2022-11-12
Description
FULL PRODUCT VERSION :
java version "9"
Java(TM) SE Runtime Environment (build 9+181)
Java HotSpot(TM) 64-Bit Server VM (build 9+181, mixed mode)

ADDITIONAL OS VERSION INFORMATION :
Linux 4.11.12-100.fc24.x86_64 #1 SMP Fri Jul 21 17:35:20 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux

A DESCRIPTION OF THE PROBLEM :
java.lang.StringCoding.encodeUTF8 (line 505) does not check for array bounds when allocating a double-sized array, when encoding a String into UTF-8 format. While the conversion would be possible (the resulting array would fit to array-size limit), an exception is thrown (stacktrace below) due to integer overflow.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
A test case is provided below.

I have actually triggered this bug when compiling a fat JAR using jaotc (JDK9 experimental feature).


ERROR MESSAGES/STACK TRACES THAT OCCUR :
Exception in thread "main" java.lang.NegativeArraySizeException
	at java.base/java.lang.StringCoding.encodeUTF8(StringCoding.java:505)
	at java.base/java.lang.StringCoding.encode(StringCoding.java:593)
	at java.base/java.lang.String.getBytes(String.java:975)
	at StringCodingOverflow.main(StringCodingOverflow.java:8)

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import java.nio.charset.Charset;
import java.util.Arrays;

public class StringCodingOverflow {
   public static void main(String[] args) {
      char[] chars = new char[(Integer.MAX_VALUE >> 1) + 1];
      Arrays.fill(chars, 'A');
      byte[] bytes = new String(chars).getBytes(Charset.forName("UTF-8"));
      System.out.printf("%d chars -> %d bytes", chars.length, bytes.length);
   }
}
---------- END SOURCE ----------


Comments
This code has changed significantly since this issue was created, it looks like it should throw OOME with recent JDK releases.
12-11-2022

it is desired to have a "safe_bound" max_array_size >> 1 check point before doing "val.length << 1"
28-09-2017

Tested on Windows 7 with JDK 9 and got the following exception: Exception in thread "main" java.lang.NegativeArraySizeException at java.base/java.lang.StringCoding.encodeUTF8(StringCoding.java:505) at java.base/java.lang.StringCoding.encode(StringCoding.java:593) at java.base/java.lang.String.getBytes(String.java:975) at JI9050995.main(JI9050995.java:9)
28-09-2017