This is an automated email from the ASF dual-hosted git repository.

opwvhk pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/avro.git


The following commit(s) were added to refs/heads/main by this push:
     new 34bdcf98ab AVRO-4182: Avoid ANTLR parsing edge cases (#3756)
34bdcf98ab is described below

commit 34bdcf98ab5d0639219f4d1ec144828e0bfa58fe
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.
---
 .../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));
   }

Reply via email to