JDK-8015421 : NegativeArraySizeException occurs in ChunkedOutputStream() with Integer.MAX_VALUE
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.net
  • Affected Version: 7,7u7,8
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2013-05-27
  • Updated: 2014-10-15
  • Resolved: 2013-06-13
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 7 JDK 8
7u66Fixed 8 b96Fixed
Description
HttpURLConnection.getOutputStream() will throw NegativeArraySizeException, if Integer.MAX_VALUE is set as the chunk size, setChunkedStreamingMode(Integer.MAX_VALUE).

Reproducible test:
------
public class Test {
    public static void main(String[] args) throws Exception {
        //Specify the URL to which you can access
        URL url = new URL("http://www.google.com");
        HttpURLConnection uc = (HttpURLConnection)url.openConnection();
        uc.setDoOutput(true);
        uc.setChunkedStreamingMode(Integer.MAX_VALUE);
        OutputStream os = uc.getOutputStream();
    }
}
------
>: java Test
Exception in thread "main" java.lang.NegativeArraySizeException
	at sun.net.www.http.ChunkedOutputStream.<init>(ChunkedOutputStream.java:128)
	at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.java:1110)
	at Test.main(Test.java:12)

Comments
buf = new byte[preferredChunkDataSize + 32] looks like the problematic statement - the array size overflows for obvious reasons when preferredChunkDataSize is Integer.MAX_VALUE
28-05-2013

API docs. of setChunkedStreamingMode() does not says the upper limit value. The size of chunk specified here. MAX_VALUE is passed to ChunkedOutputStream(). ChunkedOutputStream() tries to get an array at the following line#128. Because the specified array size is too big and parsed as a negative number, NegativeArraySizeExceptio seems to occur. ------ <jdk8> ./jdk/src/share/classes/sun/net/www/http/ChunkedOutputStream.java --- 90 public ChunkedOutputStream(PrintStream o, int size) { 91 super(o); 92 out = o; 93 94 if (size <= 0) { 95 size = DEFAULT_CHUNK_SIZE; 96 } 97 98 /* Adjust the size to cater for the chunk header - eg: if the 99 * preferred chunk size is 1k this means the chunk size should 100 * be 1017 bytes (differs by 7 from preferred size because of 101 * 3 bytes for chunk size in hex and CRLF (header) and CRLF (footer)). 102 * 103 * If headerSize(adjusted_size) is shorter then headerSize(size) 104 * then try to use the extra byte unless headerSize(adjusted_size+1) 105 * increases back to headerSize(size) 106 */ 107 if (size > 0) { 108 int adjusted_size = size - getHeaderSize(size) - FOOTER_SIZE; 109 if (getHeaderSize(adjusted_size+1) < getHeaderSize(size)){ 110 adjusted_size++; 111 } 112 size = adjusted_size; 113 } 114 115 if (size > 0) { 116 preferredChunkDataSize = size; 117 } else { 118 preferredChunkDataSize = DEFAULT_CHUNK_SIZE - 119 getHeaderSize(DEFAULT_CHUNK_SIZE) - FOOTER_SIZE; 120 } 121 122 preferedHeaderSize = getHeaderSize(preferredChunkDataSize); 123 preferredChunkGrossSize = preferedHeaderSize + preferredChunkDataSize 124 + FOOTER_SIZE; 125 completeHeader = getHeader(preferredChunkDataSize); 126 127 /* start with an initial buffer */ 128 buf = new byte[preferredChunkDataSize + 32]; 129 reset(); 130 } --------
27-05-2013