Skip to content

Commit 8178f48

Browse files
authored
Fix inconsistent exception in IOUtils.toByteArray (#796)
The implementation of `IOUtils.toByteArray(InputStream, int, int)` added in #776 throws different exceptions depending on the requested size: * For request sizes larger than the internal chunk size, it correctly throws an `EOFException`. * For smaller requests, it incorrectly throws a generic `IOException`. This PR makes the behavior consistent by always throwing an `EOFException` when the stream ends prematurely. Note: This also affects `RandomAccessFiles.read`. Its previous truncation behavior was undocumented and inconsistent with `RandomAccessFile.read` (which reads as much as possible). The new behavior is not explicitly documented here either, since it is unclear whether throwing on truncation is actually desirable.
1 parent 45578a7 commit 8178f48

File tree

2 files changed

+12
-2
lines changed

2 files changed

+12
-2
lines changed

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2941,6 +2941,7 @@ public static byte[] toByteArray(final InputStream input, final long size) throw
29412941
* @param input the input to read, not null.
29422942
* @param size the size of the input to read, where 0 < {@code size} <= length of input.
29432943
* @return byte [] of length {@code size}.
2944+
* @throws EOFException if the end of the input is reached before reading {@code size} bytes.
29442945
* @throws IOException if an I/O error occurs or input length is smaller than parameter {@code size}.
29452946
* @throws IllegalArgumentException if {@code size} is less than zero.
29462947
*/
@@ -2958,7 +2959,7 @@ static byte[] toByteArray(final IOTriFunction<byte[], Integer, Integer, Integer>
29582959
offset += read;
29592960
}
29602961
if (offset != size) {
2961-
throw new IOException("Unexpected read size, current: " + offset + ", expected: " + size);
2962+
throw new EOFException("Unexpected read size, current: " + offset + ", expected: " + size);
29622963
}
29632964
return data;
29642965
}

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

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,9 @@ static Stream<Arguments> testToByteArray_InputStream_Size_BufferSize_Throws() {
158158
Arguments.of(-1, 128, IllegalArgumentException.class),
159159
// Invalid buffer size
160160
Arguments.of(0, 0, IllegalArgumentException.class),
161-
// Huge size: should not cause OutOfMemoryError
161+
// Truncation with requested size < chunk size
162+
Arguments.of(64, 128, EOFException.class),
163+
// Truncation with requested size > chunk size
162164
Arguments.of(Integer.MAX_VALUE, 128, EOFException.class));
163165
}
164166

@@ -1788,6 +1790,13 @@ void testToByteArray_InputStream_Size() throws Exception {
17881790
}
17891791
}
17901792

1793+
@Test
1794+
void testToByteArray_InputStream_Size_Truncated() throws Exception {
1795+
try (InputStream in = new NullInputStream(0)) {
1796+
assertThrows(EOFException.class, () -> IOUtils.toByteArray(in, 1), "Should have failed with EOFException");
1797+
}
1798+
}
1799+
17911800
@ParameterizedTest
17921801
@MethodSource
17931802
void testToByteArray_InputStream_Size_BufferSize_Succeeds(final byte[] data, final int size, final int bufferSize) throws IOException {

0 commit comments

Comments
 (0)