From 4099a5b084043e71669a6e38ee4a61ad22fc53e8 Mon Sep 17 00:00:00 2001 From: Tyler Gregg Date: Mon, 30 Oct 2023 17:15:33 -0700 Subject: [PATCH] Fixes a bug that prevented early step-out of a container when positioned on a large scalar value in certain cases. --- src/com/amazon/ion/impl/IonCursorBinary.java | 2 +- ...onReaderContinuableTopLevelBinaryTest.java | 28 +++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/src/com/amazon/ion/impl/IonCursorBinary.java b/src/com/amazon/ion/impl/IonCursorBinary.java index 2548dd0372..07e89cdb0f 100644 --- a/src/com/amazon/ion/impl/IonCursorBinary.java +++ b/src/com/amazon/ion/impl/IonCursorBinary.java @@ -1470,7 +1470,7 @@ private Event slowStepOutOfContainer() { if (slowSeek(parent.endIndex - offset)) { return event; } - peekIndex = parent.endIndex; + peekIndex = offset; } setCheckpointBeforeUnannotatedTypeId(); if (--containerIndex >= 0) { diff --git a/test/com/amazon/ion/impl/IonReaderContinuableTopLevelBinaryTest.java b/test/com/amazon/ion/impl/IonReaderContinuableTopLevelBinaryTest.java index 0543df8bb3..e710f9db78 100644 --- a/test/com/amazon/ion/impl/IonReaderContinuableTopLevelBinaryTest.java +++ b/test/com/amazon/ion/impl/IonReaderContinuableTopLevelBinaryTest.java @@ -34,6 +34,7 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; import org.junit.jupiter.params.provider.ValueSource; import java.io.ByteArrayInputStream; @@ -1723,6 +1724,33 @@ public void reallyLargeString(boolean constructFromBytes) throws Exception { closeAndCount(); } + @ParameterizedTest + @CsvSource({ + "true, true", + "true, false", + "false, true", + "false, false" + }) + public void skipReallyLargeStringInContainer(boolean constructFromBytes, boolean incremental) throws Exception { + StringBuilder sb = new StringBuilder(); + // 70000 is greater than twice the default buffer size of 32768. This ensures that the string, when skipped, + // will not be fully contained in the buffer. + for (int i = 0; i < 70000; i++) { + sb.append('a'); + } + String string = sb.toString(); + readerBuilder = readerBuilder.withIncrementalReadingEnabled(incremental); + reader = readerFor("{foo: \"" + string + "\"}", constructFromBytes); + assertSequence( + container(IonType.STRUCT, + next(IonType.STRING) + // This is an early-step out that causes the string value to be skipped. + ), + next(null) + ); + closeAndCount(); + } + @ParameterizedTest(name = "constructFromBytes={0}") @ValueSource(booleans = {true, false}) public void nopPadInAnnotationWrapperFails(boolean constructFromBytes) throws Exception {