Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion src/main/java/org/apache/commons/io/IOUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -2394,10 +2394,13 @@ public static BufferedReader toBufferedReader(final Reader reader, final int siz
* @return the requested byte array.
* @throws NullPointerException if the InputStream is {@code null}.
* @throws IOException if an I/O error occurs.
* @throws IllegalArgumentException if input is longer than the maximum Java array length.
*/
public static byte[] toByteArray(final InputStream inputStream) throws IOException {
try (final ByteArrayOutputStream output = new ByteArrayOutputStream()) {
copy(inputStream, output);
if (copy(inputStream, output) == -1) {
throw new IllegalArgumentException("Stream cannot be longer than Integer max value bytes");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@leskin-in
This condition will not happen for a ByteArrayInputStream, instead of you'll get a IndexOutOfBoundsException or am I missing something?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is correct if an InputStream is a ByteArrayInputStream. However, this method accepts generic InputStream, which may wrap more data. In that case, the implementation of copy() would return -1.

However, ByteArrayOutputStream, which is created in this method as an intermediate buffer, does not check for its underlying buffer overflow at write(). The checks in write() only ensure sanity of arguments passed to it; they are valid in case of copyLarge() (ultimately called by copy() mentioned above).

The ByteArrayOutputStream, however, can store more than Integer.MAX_VALUE bytes because it can use multiple underlying byte arrays.

}
return output.toByteArray();
}
}
Expand Down
7 changes: 6 additions & 1 deletion src/test/java/org/apache/commons/io/IOUtilsTestCase.java
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
import java.util.List;

import org.apache.commons.io.function.IOConsumer;
import org.apache.commons.io.input.CircularInputStream;
import org.apache.commons.io.input.NullInputStream;
import org.apache.commons.io.output.AppendableWriter;
import org.apache.commons.io.output.NullOutputStream;
Expand Down Expand Up @@ -1435,9 +1436,13 @@ public void testToByteArray_InputStream() throws Exception {
}
}

@Test public void testToByteArray_InputStreamTooLong() throws Exception {
CircularInputStream cin = new CircularInputStream(new byte[]{65, 65, 65}, ((long)Integer.MAX_VALUE) + 1L);
assertThrows(IllegalArgumentException.class, () -> IOUtils.toByteArray(cin));
}

@Test
public void testToByteArray_InputStream_NegativeSize() throws Exception {

try (FileInputStream fin = new FileInputStream(testFile)) {
IOUtils.toByteArray(fin, -1);
fail("IllegalArgumentException expected");
Expand Down