This is an automated email from the ASF dual-hosted git repository. opwvhk pushed a commit to branch branch-1.12 in repository https://gitbox.apache.org/repos/asf/avro.git
commit 30c81a354dee27396f1e86d79dfbb819bb7388a4 Author: Oscar Westra van Holthe - Kind <[email protected]> AuthorDate: Fri May 15 18:55:10 2026 +0200 AVRO-4182: Avoid ANTLR parsing edge cases (#3756) In some cases, enter and exit rules are not called in pairs while parsing. Apparently, this is by design. This fix adds a test that the fix does indeed work (it tests an exception, as the error does not show up with a duplicated definition). Note: this change keeps the entire parse tree in memory during parsing, and allows it to be collected directly afterwards. (cherry picked from commit 34bdcf98ab5d0639219f4d1ec144828e0bfa58fe) --- .../idl/src/main/java/org/apache/avro/idl/IdlReader.java | 14 ++++++++------ .../idl/src/test/idl/extra/duplicateNameErrorParsing.avdl | 14 ++++++++++++++ .../src/test/java/org/apache/avro/idl/TestIdlReader.java | 12 +++++++++++- 3 files changed, 33 insertions(+), 7 deletions(-) diff --git a/lang/java/idl/src/main/java/org/apache/avro/idl/IdlReader.java b/lang/java/idl/src/main/java/org/apache/avro/idl/IdlReader.java index f6d1fb49dc..85c7d5a568 100644 --- a/lang/java/idl/src/main/java/org/apache/avro/idl/IdlReader.java +++ b/lang/java/idl/src/main/java/org/apache/avro/idl/IdlReader.java @@ -34,6 +34,7 @@ import org.antlr.v4.runtime.ParserRuleContext; import org.antlr.v4.runtime.RecognitionException; import org.antlr.v4.runtime.Recognizer; import org.antlr.v4.runtime.Token; +import org.antlr.v4.runtime.tree.ParseTreeWalker; import org.apache.avro.JsonProperties; import org.apache.avro.JsonSchemaParser; import org.apache.avro.LogicalType; @@ -207,20 +208,21 @@ public class IdlReader { IdlParser parser = new IdlParser(tokenStream); parser.removeErrorListeners(); parser.addErrorListener(SIMPLE_AVRO_ERROR_LISTENER); - parser.addParseListener(parseListener); parser.setTrace(false); - parser.setBuildParseTree(false); + // Parse the input, then walk the parse tree using the listener. + // Although the parse can call the listener directly, there are edge cases where + // the enter and exit rules are not called in pairs. This a known issue and + // currently by design. See: https://github.com/antlr/antlr4/issues/18 try { - // Trigger parsing. - parser.idlFile(); + IdlFileContext idlFileContext = parser.idlFile(); + ParseTreeWalker.DEFAULT.walk(parseListener, idlFileContext); + return parseListener.getIdlFile(); } catch (SchemaParseException e) { throw e; } catch (RuntimeException e) { throw new SchemaParseException(e); } - - return parseListener.getIdlFile(); } /* Package private to facilitate testing */ diff --git a/lang/java/idl/src/test/idl/extra/duplicateNameErrorParsing.avdl b/lang/java/idl/src/test/idl/extra/duplicateNameErrorParsing.avdl new file mode 100644 index 0000000000..f6700b0d77 --- /dev/null +++ b/lang/java/idl/src/test/idl/extra/duplicateNameErrorParsing.avdl @@ -0,0 +1,14 @@ +namespace duplicateNameParseError; + +// Test that parsing fails when redefining an enum with different symbols. +// Avro 1.12.0 fails to parse this, but the correct result is an explicit error that redefinition is not allowed. + +enum Foo { + UNKNOWN, + BAR +} = UNKNOWN; + +enum Foo { + UNKNOWN, + BAZ +} = UNKNOWN; diff --git a/lang/java/idl/src/test/java/org/apache/avro/idl/TestIdlReader.java b/lang/java/idl/src/test/java/org/apache/avro/idl/TestIdlReader.java index 96034cf395..d437f9299b 100644 --- a/lang/java/idl/src/test/java/org/apache/avro/idl/TestIdlReader.java +++ b/lang/java/idl/src/test/java/org/apache/avro/idl/TestIdlReader.java @@ -21,6 +21,7 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.avro.Protocol; import org.apache.avro.Schema; +import org.apache.avro.SchemaParseException; import org.junit.Before; import org.junit.Test; import java.io.BufferedReader; @@ -156,7 +157,16 @@ public class TestIdlReader { warnings); } - @SuppressWarnings("SameParameterValue") + @Test + public void testErrorDuplicateNamedType() throws IOException { + try { + parseExtraIdlFile("duplicateNameErrorParsing.avdl"); + fail("Expected a failure: named schemas cannot be redefined."); + } catch (SchemaParseException e) { + assertEquals("Can't redefine: duplicateNameParseError.Foo", e.getMessage()); + } + } + private IdlFile parseExtraIdlFile(String fileName) throws IOException { return new IdlReader().parse(EXTRA_TEST_DIR.toPath().resolve(fileName)); }
