From 2d9ff8ca53033a935947ff034885e8ea5dfa33c5 Mon Sep 17 00:00:00 2001 From: Pierre Maurice Schwang Date: Thu, 14 Nov 2024 23:04:53 +0100 Subject: [PATCH] fix: allow empty snbt compounds using LinSnbtReader --- .../snbt/impl/reader/LinSnbtReader.java | 8 ++++-- .../snbt/impl/reader/LinSnbtReaderTest.java | 25 +++++++++++++++++-- 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/format-snbt/src/main/java/org/enginehub/linbus/format/snbt/impl/reader/LinSnbtReader.java b/format-snbt/src/main/java/org/enginehub/linbus/format/snbt/impl/reader/LinSnbtReader.java index bcfeb0b..4605570 100644 --- a/format-snbt/src/main/java/org/enginehub/linbus/format/snbt/impl/reader/LinSnbtReader.java +++ b/format-snbt/src/main/java/org/enginehub/linbus/format/snbt/impl/reader/LinSnbtReader.java @@ -225,7 +225,6 @@ private void readValue(State.ReadValue readValue) { var token = read().token(); if (token instanceof SnbtToken.CompoundStart) { stateStack.addLast(State.InCompound.INSTANCE); - stateStack.addLast(State.CompoundEntryName.INSTANCE); tokenQueue.addLast(new LinToken.CompoundStart()); return; } @@ -245,8 +244,13 @@ private void readValue(State.ReadValue readValue) { } private void advanceCompound() { - var token = read().token(); + var typing = read(); + var token = typing.token(); switch (token) { + case SnbtToken.Text text -> { + readAgainStack.addLast(typing); + stateStack.addLast(State.CompoundEntryName.INSTANCE); + } case SnbtToken.CompoundEnd compoundEnd -> { stateStack.removeLast(); tokenQueue.addLast(new LinToken.CompoundEnd()); diff --git a/format-snbt/src/test/java/org/enginehub/linbus/format/snbt/impl/reader/LinSnbtReaderTest.java b/format-snbt/src/test/java/org/enginehub/linbus/format/snbt/impl/reader/LinSnbtReaderTest.java index bf8a6d7..3a7138c 100644 --- a/format-snbt/src/test/java/org/enginehub/linbus/format/snbt/impl/reader/LinSnbtReaderTest.java +++ b/format-snbt/src/test/java/org/enginehub/linbus/format/snbt/impl/reader/LinSnbtReaderTest.java @@ -74,6 +74,27 @@ void invalidCharacterAfterSimpleValue() throws IOException { assertThat(ex).hasMessageThat().isEqualTo(atCharacterIndex(3) + "Unexpected token: ';'"); } + @Test + void emptyRootCompound() { + var list = ImmutableList.copyOf(ezStringRead("{}").asIterator()); + assertThat(list).containsExactly(new LinToken.CompoundStart(), new LinToken.CompoundEnd()).inOrder(); + + list = ImmutableList.copyOf(ezStringRead("{ }").asIterator()); + assertThat(list).containsExactly(new LinToken.CompoundStart(), new LinToken.CompoundEnd()).inOrder(); + } + + @Test + void emptyNestedCompound() { + var list = ImmutableList.copyOf(ezStringRead("{nested:{}}").asIterator()); + assertThat(list).containsExactly( + new LinToken.CompoundStart(), + new LinToken.Name("nested"), + new LinToken.CompoundStart(), + new LinToken.CompoundEnd(), + new LinToken.CompoundEnd() + ).inOrder(); + } + @Test void simpleValueWithWhitespace() { var list = ImmutableList.copyOf(ezStringRead("{a:b }").asIterator()); @@ -168,7 +189,7 @@ void badName() throws IOException { var reader = ezStringRead("{;"); assertThat(reader.nextOrNull()).isEqualTo(new LinToken.CompoundStart()); var ex = assertThrows(NbtParseException.class, reader::nextOrNull); - assertThat(ex).hasMessageThat().isEqualTo(atCharacterIndex(1) + "Unexpected token: ';', expected Text"); + assertThat(ex).hasMessageThat().isEqualTo(atCharacterIndex(1) + "Unexpected token: ';'"); } @Test @@ -186,7 +207,7 @@ void badCompoundEnd() throws IOException { assertThat(reader.nextOrNull()).isEqualTo(new LinToken.Name("a")); assertThat(reader.nextOrNull()).isEqualTo(new LinToken.String("@")); var ex = assertThrows(NbtParseException.class, reader::nextOrNull); - assertThat(ex).hasMessageThat().isEqualTo(atCharacterIndex(6) + "Unexpected token: Text[quoted=false, content=b]"); + assertThat(ex).hasMessageThat().isEqualTo(atCharacterIndex(6) + "Unexpected end of input"); } @Test