From 740f2500a7686bb5afe51fd488d501b8ee10006d Mon Sep 17 00:00:00 2001 From: mohammed arib Date: Wed, 29 Jul 2026 13:07:54 +0530 Subject: [PATCH] [java] escape backslashes in escapeForJavadoc to stop comment breakout --- .../compiler/specific/SpecificCompiler.java | 6 +++++- .../specific/TestSpecificCompiler.java | 21 +++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/lang/java/compiler/src/main/java/org/apache/avro/compiler/specific/SpecificCompiler.java b/lang/java/compiler/src/main/java/org/apache/avro/compiler/specific/SpecificCompiler.java index 4cfe1eea48c..961bdf3aa31 100644 --- a/lang/java/compiler/src/main/java/org/apache/avro/compiler/specific/SpecificCompiler.java +++ b/lang/java/compiler/src/main/java/org/apache/avro/compiler/specific/SpecificCompiler.java @@ -1118,7 +1118,11 @@ public static String javaEscape(String o) { * Utility for template use. Escapes comment end with HTML entities. */ public static String escapeForJavadoc(String s) { - return s.replace("*/", "*/").replace("<", "<").replace(">", ">"); + // Double backslashes first so a value cannot smuggle in a Unicode escape such + // as \\u002a\\u002f: javac processes Unicode escapes before comments, so an + // unneutralized \\u002a\\u002f would decode to */ inside the generated Javadoc + // and let a schema doc break out of the comment into code. + return s.replace("\\", "\\\\").replace("*/", "*/").replace("<", "<").replace(">", ">"); } /** diff --git a/lang/java/compiler/src/test/java/org/apache/avro/compiler/specific/TestSpecificCompiler.java b/lang/java/compiler/src/test/java/org/apache/avro/compiler/specific/TestSpecificCompiler.java index 918e28a8954..36a7fd78322 100644 --- a/lang/java/compiler/src/test/java/org/apache/avro/compiler/specific/TestSpecificCompiler.java +++ b/lang/java/compiler/src/test/java/org/apache/avro/compiler/specific/TestSpecificCompiler.java @@ -1058,6 +1058,27 @@ void annotationCannotBreakOutViaStringLiteral() { assertTrue(validAnnotationEmitted, "Valid annotation missing from generated output"); } + @Test + void docCannotBreakOutViaUnicodeEscape() { + // javac decodes Unicode escapes before it strips comments, so a schema doc + // carrying a backslash-u escape for the comment terminator decodes to that + // terminator inside the generated Javadoc and ends the comment early, turning + // the rest of the doc into code. The escaper must neutralize such escapes. + String jsonSchema = "{\n" + " \"type\": \"record\",\n" + " \"name\": \"DocInjected\",\n" + " \"fields\": [\n" + + " {\"name\": \"value\", \"type\": \"string\", \"doc\": " + + "\"\\\\u002a\\\\u002f public static int PWNED = 1; \\\\u002f\\\\u002a\"}\n" + " ]\n" + "}"; + Collection outputs = new SpecificCompiler(SchemaParser.parseSingle(jsonSchema)) + .compile(); + // A Unicode escape is only decoded by javac when the leading backslash is + // preceded by an even number of backslashes. An eligible escape for a comment + // char in the generated source is the breakout; the doubled form is inert. + Pattern eligibleEscape = Pattern.compile("(?