This is an automated email from the ASF dual-hosted git repository.

pkarwasz pushed a commit to branch fix/io-utils-eof
in repository https://gitbox.apache.org/repos/asf/commons-io.git

commit 792947fc0552a984da52e2c6f42d61311361a6c8
Author: Piotr P. Karwasz <[email protected]>
AuthorDate: Fri Oct 3 20:40:43 2025 +0200

    Fix inconsistent exception in `IOUtils.toByteArray`
    
    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.
---
 src/main/java/org/apache/commons/io/IOUtils.java     |  3 ++-
 src/test/java/org/apache/commons/io/IOUtilsTest.java | 11 ++++++++++-
 2 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/src/main/java/org/apache/commons/io/IOUtils.java 
b/src/main/java/org/apache/commons/io/IOUtils.java
index a882d4d87..e157d51a5 100644
--- a/src/main/java/org/apache/commons/io/IOUtils.java
+++ b/src/main/java/org/apache/commons/io/IOUtils.java
@@ -2957,6 +2957,7 @@ public static byte[] toByteArray(final InputStream input, 
final long size) throw
      * @param input the input to read, not null.
      * @param size the size of the input to read, where 0 &lt; {@code size} 
&lt;= length of input.
      * @return byte [] of length {@code size}.
+     * @throws EOFException if the end of the input is reached before reading 
{@code size} bytes.
      * @throws IOException if an I/O error occurs or input length is smaller 
than parameter {@code size}.
      * @throws IllegalArgumentException if {@code size} is less than zero.
      */
@@ -2974,7 +2975,7 @@ static byte[] toByteArray(final IOTriFunction<byte[], 
Integer, Integer, Integer>
             offset += read;
         }
         if (offset != size) {
-            throw new IOException("Unexpected read size, current: " + offset + 
", expected: " + size);
+            throw new EOFException("Unexpected read size, current: " + offset 
+ ", expected: " + size);
         }
         return data;
     }
diff --git a/src/test/java/org/apache/commons/io/IOUtilsTest.java 
b/src/test/java/org/apache/commons/io/IOUtilsTest.java
index 02574946b..df05c648f 100644
--- a/src/test/java/org/apache/commons/io/IOUtilsTest.java
+++ b/src/test/java/org/apache/commons/io/IOUtilsTest.java
@@ -158,7 +158,9 @@ static Stream<Arguments> 
testToByteArray_InputStream_Size_BufferSize_Throws() {
                 Arguments.of(-1, 128, IllegalArgumentException.class),
                 // Invalid buffer size
                 Arguments.of(0, 0, IllegalArgumentException.class),
-                // Huge size: should not cause OutOfMemoryError
+                // Truncation with requested size < chunk size
+                Arguments.of(64, 128, EOFException.class),
+                // Truncation with requested size > chunk size
                 Arguments.of(Integer.MAX_VALUE, 128, EOFException.class));
     }
 
@@ -1757,6 +1759,13 @@ void testToByteArray_InputStream_Size() throws Exception 
{
         }
     }
 
+    @Test
+    void testToByteArray_InputStream_Size_Truncated() throws Exception {
+        try (InputStream in = new NullInputStream(0)) {
+            assertThrows(EOFException.class, () -> IOUtils.toByteArray(in, 1), 
"Should have failed with EOFException");
+        }
+    }
+
     @ParameterizedTest
     @MethodSource
     void testToByteArray_InputStream_Size_BufferSize_Succeeds(final byte[] 
data, final int size, final int bufferSize) throws IOException {

Reply via email to