Skip to content

Commit 7e0d317

Browse files
author
Gary Gregory
committed
[IO-429] Check for long streams in IOUtils.toByteArray #175.
1 parent 3f989cc commit 7e0d317

3 files changed

Lines changed: 22 additions & 4 deletions

File tree

src/changes/changes.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,9 @@ The <action> type attribute can be add,update,fix,remove.
126126
<action dev="ggregory" type="fix" due-to="Rob Spoor, Gary Gregory">
127127
Prevent infinite loop with AbstractCharacterFilterReader if EOF is filtered out #226.
128128
</action>
129+
<action issue="IO-429" dev="ggregory" type="fix" due-to="Rob Spoor, Ivan Leskin">
130+
Check for long streams in IOUtils.toByteArray #175.
131+
</action>
129132
<!-- ADD -->
130133
<action dev="ggregory" type="add" due-to="Gary Gregory">
131134
Add FileSystemProviders class.

src/main/java/org/apache/commons/io/IOUtils.java

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
import org.apache.commons.io.output.ByteArrayOutputStream;
5656
import org.apache.commons.io.output.NullOutputStream;
5757
import org.apache.commons.io.output.StringBuilderWriter;
58+
import org.apache.commons.io.output.ThresholdingOutputStream;
5859
import org.apache.commons.io.output.UnsynchronizedByteArrayOutputStream;
5960

6061
/**
@@ -2394,12 +2395,17 @@ public static BufferedReader toBufferedReader(final Reader reader, final int siz
23942395
* @param inputStream the {@code InputStream} to read.
23952396
* @return the requested byte array.
23962397
* @throws NullPointerException if the InputStream is {@code null}.
2397-
* @throws IOException if an I/O error occurs.
2398+
* @throws IOException if an I/O error occurs or reading more than {@link Integer#MAX_VALUE} occurs.
23982399
*/
23992400
public static byte[] toByteArray(final InputStream inputStream) throws IOException {
2400-
try (final UnsynchronizedByteArrayOutputStream output = new UnsynchronizedByteArrayOutputStream()) {
2401-
copy(inputStream, output);
2402-
return output.toByteArray();
2401+
// We use a ThresholdingOutputStream to avoid reading AND writing more than Integer.MAX_VALUE.
2402+
try (final UnsynchronizedByteArrayOutputStream ubaOutput = new UnsynchronizedByteArrayOutputStream();
2403+
final ThresholdingOutputStream thresholdOuput = new ThresholdingOutputStream(Integer.MAX_VALUE, os -> {
2404+
throw new IllegalArgumentException(
2405+
String.format("Cannot read more than %,d into a byte array", Integer.MAX_VALUE));
2406+
}, os -> ubaOutput)) {
2407+
copy(inputStream, thresholdOuput);
2408+
return ubaOutput.toByteArray();
24032409
}
24042410
}
24052411

src/test/java/org/apache/commons/io/IOUtilsTestCase.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,13 +62,15 @@
6262
import java.util.List;
6363

6464
import org.apache.commons.io.function.IOConsumer;
65+
import org.apache.commons.io.input.CircularInputStream;
6566
import org.apache.commons.io.input.NullInputStream;
6667
import org.apache.commons.io.output.AppendableWriter;
6768
import org.apache.commons.io.output.NullOutputStream;
6869
import org.apache.commons.io.output.StringBuilderWriter;
6970
import org.apache.commons.io.test.TestUtils;
7071
import org.apache.commons.io.test.ThrowOnCloseReader;
7172
import org.junit.jupiter.api.BeforeEach;
73+
import org.junit.jupiter.api.Disabled;
7274
import org.junit.jupiter.api.Test;
7375
import org.junit.jupiter.api.io.TempDir;
7476

@@ -1435,6 +1437,13 @@ public void testToByteArray_InputStream() throws Exception {
14351437
}
14361438
}
14371439

1440+
@Test
1441+
@Disabled("Disable by default as it uses too much memory and can cause builds to fail.")
1442+
public void testToByteArray_InputStream_LongerThanIntegerMaxValue() throws Exception {
1443+
final CircularInputStream cin = new CircularInputStream(IOUtils.byteArray(), Integer.MAX_VALUE + 1L);
1444+
assertThrows(IllegalArgumentException.class, () -> IOUtils.toByteArray(cin));
1445+
}
1446+
14381447
@Test
14391448
public void testToByteArray_InputStream_NegativeSize() throws Exception {
14401449

0 commit comments

Comments
 (0)