diff --git a/src/main/java/org/apache/xmlbeans/impl/schema/SchemaTypeCodePrinter.java b/src/main/java/org/apache/xmlbeans/impl/schema/SchemaTypeCodePrinter.java index 9a3a1c8c3..15178d5dd 100644 --- a/src/main/java/org/apache/xmlbeans/impl/schema/SchemaTypeCodePrinter.java +++ b/src/main/java/org/apache/xmlbeans/impl/schema/SchemaTypeCodePrinter.java @@ -168,7 +168,7 @@ static String prettyQName(QName qname) { } String result = qname.getLocalPart(); if (qname.getNamespaceURI() != null) { - result += "(@" + qname.getNamespaceURI() + ")"; + result += "(@" + javaCommentEscape(qname.getNamespaceURI()) + ")"; } return result; } @@ -345,7 +345,7 @@ void printTopComment(SchemaType sType) throws IOException { emit("/*"); if (sType.getName() != null) { emit(" * XML Type: " + sType.getName().getLocalPart()); - emit(" * Namespace: " + sType.getName().getNamespaceURI()); + emit(" * Namespace: " + javaCommentEscape(sType.getName().getNamespaceURI())); } else { QName thename = null; @@ -362,7 +362,7 @@ void printTopComment(SchemaType sType) throws IOException { assert (thename != null); emit(" * Localname: " + thename.getLocalPart()); - emit(" * Namespace: " + thename.getNamespaceURI()); + emit(" * Namespace: " + javaCommentEscape(thename.getNamespaceURI())); } emit(" * Java type: " + sType.getFullJavaName()); emit(" *"); @@ -504,15 +504,21 @@ void printJavaDocParagraph(String s) throws IOException{ void printJavaDocBody(String doc) throws IOException{ // add some poor mans code injection protection // this is not protecting against annotation based RCEs like CVE-2018-16621 - String docClean = doc.trim() - .replace("\t", "") - .replace("*/", "* /"); + String docClean = javaCommentEscape(doc.trim().replace("\t", "")); for (String s : docClean.split("[\\n\\r]+")) { emit(" * " + s); } } + public static String javaCommentEscape(String str) + { + // forbidden: */, and the backslash of a unicode escape - those are decoded + // before comments are recognized (JLS 3.3), so an escaped */ ends the + // comment too and the rest of the schema text is compiled as code + return str.replace("\\", "\\\\").replace("*/", "* /"); + } + public static String javaStringEscape(String str) { // forbidden: \n, \r, \", \\. @@ -1427,7 +1433,7 @@ void printStaticFields(SchemaProperty[] properties, Map s = Files.walk(classesdir.toPath())) { + assertFalse(s.anyMatch(f -> "Pwned.class".equals(f.getFileName().toString())), + "class injected through the schema documentation"); + } + } + //TESTENV: private static void dumpErrors(List errors, PrintWriter out) { diff --git a/src/test/resources/xbean/compile/scomp/schemacompiler/codeinject.xsd b/src/test/resources/xbean/compile/scomp/schemacompiler/codeinject.xsd new file mode 100644 index 000000000..52cccae1b --- /dev/null +++ b/src/test/resources/xbean/compile/scomp/schemacompiler/codeinject.xsd @@ -0,0 +1,34 @@ + + + + + + + + + a doc \u002a\u002f class Pwned {} /** + + + + + + + +