diff --git a/src/com/amazon/ion/impl/IonCursorBinary.java b/src/com/amazon/ion/impl/IonCursorBinary.java index 1f25bbec9..cfa2740e7 100644 --- a/src/com/amazon/ion/impl/IonCursorBinary.java +++ b/src/com/amazon/ion/impl/IonCursorBinary.java @@ -389,7 +389,10 @@ private static IonBufferConfiguration getFixedSizeConfigurationFor( ByteArrayInputStream inputStream, int alreadyReadLen ) { - int fixedBufferSize = inputStream.available(); + // Note: ByteArrayInputStream.available() can return a negative number because its constructor does + // not validate that the offset and length provided are actually within range of the provided byte array. + // Setting the result to 0 in this case avoids an error when looking up the fixed sized configuration. + int fixedBufferSize = Math.max(0, inputStream.available()); if (alreadyReadLen > 0) { fixedBufferSize += alreadyReadLen; } diff --git a/test/com/amazon/ion/impl/IonReaderContinuableTopLevelBinaryTest.java b/test/com/amazon/ion/impl/IonReaderContinuableTopLevelBinaryTest.java index 1318cc55a..3bf42d28b 100644 --- a/test/com/amazon/ion/impl/IonReaderContinuableTopLevelBinaryTest.java +++ b/test/com/amazon/ion/impl/IonReaderContinuableTopLevelBinaryTest.java @@ -3321,6 +3321,17 @@ public void concatenatedAfterMissingGZIPTrailer() throws Exception { assertEquals(1, oversizedCounter.get()); } + @Test + public void shouldNotFailWhenProvidedWithAnEmptyByteArrayInputStream() throws Exception { + reader = IonReaderBuilder.standard().build(new ByteArrayInputStream(new byte[]{})); + assertSequence(next(null)); + reader.close(); + // The following ByteArrayInputStream is weird, but not disallowed. Its available() method will return -1. + reader = IonReaderBuilder.standard().build(new ByteArrayInputStream(new byte[]{}, 1, 1)); + assertSequence(next(null)); + reader.close(); + } + @ParameterizedTest(name = "constructFromBytes={0}") @ValueSource(booleans = {true, false}) public void incompleteContainerNonContinuable(boolean constructFromBytes) throws Exception {