Skip to content

Commit

Permalink
Fixes a bug that caused the binary reader not to fail cleanly when pa…
Browse files Browse the repository at this point in the history
…rsing incomplete containers in certain cases.
tgregg committed Feb 2, 2024

Verified

This commit was signed with the committer’s verified signature.
1 parent 8dbd001 commit d0a4a4a
Showing 2 changed files with 74 additions and 0 deletions.
3 changes: 3 additions & 0 deletions src/main/java/com/amazon/ion/impl/IonCursorBinary.java
Original file line number Diff line number Diff line change
@@ -1574,6 +1574,9 @@ private boolean uncheckedNextToken() {
if (uncheckedNextContainedToken()) {
return false;
}
if (peekIndex >= limit) {
throw new IonException("Malformed data: declared length exceeds the number of bytes remaining in the container.");
}
b = buffer[(int)(peekIndex++)] & SINGLE_BYTE_MASK;
}
if (uncheckedReadHeader(b, false, valueMarker)) {
Original file line number Diff line number Diff line change
@@ -3,6 +3,7 @@

package com.amazon.ion.impl;

import com.amazon.ion.IonCursor;
import com.amazon.ion.IonException;
import com.amazon.ion.IonType;
import org.junit.jupiter.api.Test;
@@ -496,4 +497,74 @@ public void expectLobWithOverflowingEndIndexToFailCleanly(boolean constructFromB
assertThrows(IonException.class, reader::nextValue);
reader.close();
}

@Test
public void expectIncompleteContainerToFailCleanlyAfterFieldSid() {
IonReaderContinuableCoreBinary reader = initializeReader(
true,
0xE0, 0x01, 0x00, 0xEA, // IVM
0xDC, // Struct, length 12
0x9A // Field SID 26
// The struct ends unexpectedly
);
assertEquals(IonCursor.Event.START_CONTAINER, reader.nextValue());
assertEquals(IonType.STRUCT, reader.getType());
reader.stepIntoContainer();
// This is an unexpected EOF, so the reader should fail cleanly.
assertThrows(IonException.class, reader::nextValue);
reader.close();
}

@Test
public void expectIncompleteContainerToFailCleanlyAfterTwoByteFieldSid() {
IonReaderContinuableCoreBinary reader = initializeReader(
true,
0xE0, 0x01, 0x00, 0xEA, // IVM
0xDC, // Struct, length 12
0x00, // First byte of overpadded 2-byte field SID
0x9A // Field SID 26
// The struct ends unexpectedly
);
assertEquals(IonCursor.Event.START_CONTAINER, reader.nextValue());
assertEquals(IonType.STRUCT, reader.getType());
reader.stepIntoContainer();
// This is an unexpected EOF, so the reader should fail cleanly.
assertThrows(IonException.class, reader::nextValue);
reader.close();
}

@Test
public void expectIncompleteContainerToFailCleanlyAfterAnnotationHeader() {
IonReaderContinuableCoreBinary reader = initializeReader(
true,
0xE0, 0x01, 0x00, 0xEA, // IVM
0xDC, // Struct, length 12
0x9A, // Field SID 26
0xE4, // Annotation wrapper length 4
0x00, 0x81, // VarUInt length 1 (overpadded by 1 byte)
0x00, 0x84 // VarUInt SID 4 (overpadded by 1 byte)
// The value ends unexpectedly
);
assertEquals(IonCursor.Event.START_CONTAINER, reader.nextValue());
assertEquals(IonType.STRUCT, reader.getType());
reader.stepIntoContainer();
// This is an unexpected EOF, so the reader should fail cleanly.
assertThrows(IonException.class, reader::nextValue);
reader.close();
}

@Test
public void expectIncompleteAnnotationHeaderToFailCleanly() {
IonReaderContinuableCoreBinary reader = initializeReader(
true,
0xE0, 0x01, 0x00, 0xEA, // IVM
0xE4, // Annotation wrapper length 5
0x81, // VarUInt length 1
0x84 // VarUInt SID 4
// The value ends unexpectedly
);
// This is an unexpected EOF, so the reader should fail cleanly.
assertThrows(IonException.class, reader::nextValue);
reader.close();
}
}

0 comments on commit d0a4a4a

Please sign in to comment.