Details
-
Bug
-
Status: Resolved
-
Major
-
Resolution: Fixed
-
2.13.0
-
None
-
JDK 17.0
Apache commons-io-2.13.0, but it looks like this apply to 2.15.0 too.
Description
A java.io.InputStream instance's read(...) method will always return -1 after it reaches its end.
However, after a NullInputStream instance reaches its end, if you call its read(...) method again, you'll get IOException with message Read after end of file. It's document says the read(...) method should return -1 if the end of file has been reached and throwEofException is set to false. However, its code doesn't check throwEofException flag before it throws the IOException:
public int read() throws IOException { if (eof) { throw new IOException("Read after end of file"); } .... }
I'm not sure whether its read method should strictly follow what InputStream does, i.e., always return -1 after it reaches end, or should it check throwEofException flag before it throws an IOException.
Following is a snippet that can reproduce this problem:
import org.apache.commons.io.input.NullInputStream; import java.io.ByteArrayInputStream; import java.io.InputStream; public class InputStreamTest { private static void testOneStream(InputStream inputStream) throws Exception { final byte[] buffer = new byte[4096]; int readLen; while ((readLen = inputStream.read(buffer)) != -1) { // do nothing } readLen = inputStream.read(buffer); if (readLen != -1) { throw new Exception("Failed to read after reaching the end of the stream."); } } public static void main(String[] args) { try { // Test ByteArrayInputStream final InputStream byteArrayInputStream = new ByteArrayInputStream(new byte[1024]); testOneStream(byteArrayInputStream); System.out.println("ByteArrayInputStream succeeded."); } catch (Exception e) { System.out.println("ByteArrayInputStream failed"); } try { //Test NullInputStream final InputStream nullInputStream = new NullInputStream(1024, true, false); testOneStream(nullInputStream); System.out.println("NullInputStream succeeded."); } catch (Exception e) { System.out.println("NullInputStream failed"); } } }