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.
  • Loading branch information
tgregg committed Feb 2, 2024
1 parent 8dbd001 commit d0a4a4a
Show file tree
Hide file tree
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
Expand Up @@ -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)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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.