Skip to content

Commit 08752c2

Browse files
committed
Fixes a bug that caused the binary reader not to fail cleanly when parsing incomplete containers in certain cases.
1 parent 8dbd001 commit 08752c2

File tree

2 files changed

+74
-0
lines changed

2 files changed

+74
-0
lines changed

src/main/java/com/amazon/ion/impl/IonCursorBinary.java

+3
Original file line numberDiff line numberDiff line change
@@ -1574,6 +1574,9 @@ private boolean uncheckedNextToken() {
15741574
if (uncheckedNextContainedToken()) {
15751575
return false;
15761576
}
1577+
if (peekIndex >= limit) {
1578+
throw new IonException("Malformed data: declared length exceeds the number of bytes remaining in the container.");
1579+
}
15771580
b = buffer[(int)(peekIndex++)] & SINGLE_BYTE_MASK;
15781581
}
15791582
if (uncheckedReadHeader(b, false, valueMarker)) {

src/test/java/com/amazon/ion/impl/IonReaderContinuableCoreBinaryTest.java

+71
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
package com.amazon.ion.impl;
55

6+
import com.amazon.ion.IonCursor;
67
import com.amazon.ion.IonException;
78
import com.amazon.ion.IonType;
89
import org.junit.jupiter.api.Test;
@@ -496,4 +497,74 @@ public void expectLobWithOverflowingEndIndexToFailCleanly(boolean constructFromB
496497
assertThrows(IonException.class, reader::nextValue);
497498
reader.close();
498499
}
500+
501+
@Test
502+
public void expectIncompleteContainerToFailCleanlyAfterFieldSid() {
503+
IonReaderContinuableCoreBinary reader = initializeReader(
504+
true,
505+
0xE0, 0x01, 0x00, 0xEA, // IVM
506+
0xDC, // Struct, length 12
507+
0x9A // Field SID 26
508+
// The struct ends unexpectedly
509+
);
510+
assertEquals(IonCursor.Event.START_CONTAINER, reader.nextValue());
511+
assertEquals(IonType.STRUCT, reader.getType());
512+
reader.stepIntoContainer();
513+
// This is an unexpected EOF, so the reader should fail cleanly.
514+
assertThrows(IonException.class, reader::nextValue);
515+
reader.close();
516+
}
517+
518+
@Test
519+
public void expectIncompleteContainerToFailCleanlyAfterTwoByteFieldSid() {
520+
IonReaderContinuableCoreBinary reader = initializeReader(
521+
true,
522+
0xE0, 0x01, 0x00, 0xEA, // IVM
523+
0xDC, // Struct, length 12
524+
0x00, // First byte of overpadded 2-byte field SID
525+
0x9A // Field SID 26
526+
// The struct ends unexpectedly
527+
);
528+
assertEquals(IonCursor.Event.START_CONTAINER, reader.nextValue());
529+
assertEquals(IonType.STRUCT, reader.getType());
530+
reader.stepIntoContainer();
531+
// This is an unexpected EOF, so the reader should fail cleanly.
532+
assertThrows(IonException.class, reader::nextValue);
533+
reader.close();
534+
}
535+
536+
@Test
537+
public void expectIncompleteContainerToFailCleanlyAfterAnnotationHeader() {
538+
IonReaderContinuableCoreBinary reader = initializeReader(
539+
true,
540+
0xE0, 0x01, 0x00, 0xEA, // IVM
541+
0xDC, // Struct, length 12
542+
0x9A, // Field SID 26
543+
0xE4, // Annotation wrapper length 4
544+
0x00, 0x81, // VarUInt length 1 (overpadded by 1 byte)
545+
0x00, 0x84 // VarUInt SID 4 (overpadded by 1 byte)
546+
// The value ends unexpectedly
547+
);
548+
assertEquals(IonCursor.Event.START_CONTAINER, reader.nextValue());
549+
assertEquals(IonType.STRUCT, reader.getType());
550+
reader.stepIntoContainer();
551+
// This is an unexpected EOF, so the reader should fail cleanly.
552+
assertThrows(IonException.class, reader::nextValue);
553+
reader.close();
554+
}
555+
556+
@Test
557+
public void expectIncompleteAnnotationHeaderToFailCleanly() {
558+
IonReaderContinuableCoreBinary reader = initializeReader(
559+
true,
560+
0xE0, 0x01, 0x00, 0xEA, // IVM
561+
0xE4, // Annotation wrapper length 5
562+
0x81, // VarUInt length 1
563+
0x84 // VarUInt SID 4
564+
// The value ends unexpectedly
565+
);
566+
// This is an unexpected EOF, so the reader should fail cleanly.
567+
assertThrows(IonException.class, reader::nextValue);
568+
reader.close();
569+
}
499570
}

0 commit comments

Comments
 (0)