You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@poi.apache.org by ki...@apache.org on 2021/06/20 21:41:08 UTC
svn commit: r1890934 - in /xmlbeans/trunk/src:
main/java/org/apache/xmlbeans/ main/java/org/apache/xmlbeans/impl/schema/
main/java/org/apache/xmlbeans/impl/tool/ main/resources/maven/
test/java/compile/scomp/checkin/ test/resources/xbean/compile/scomp/...
Author: kiwiwings
Date: Sun Jun 20 21:41:08 2021
New Revision: 1890934
URL: http://svn.apache.org/viewvc?rev=1890934&view=rev
Log:
add code injection filter
doesn't protect against "Expression Language Injection", therefore I've added an schema compiler option to activate the copying of the annotation which is by default off
Added:
xmlbeans/trunk/src/test/resources/xbean/compile/scomp/schemacompiler/javadoc.xsd
- copied, changed from r1890294, xmlbeans/trunk/src/test/resources/xbean/compile/scomp/partials/partialMethods.xsd
Modified:
xmlbeans/trunk/src/main/java/org/apache/xmlbeans/XmlOptions.java
xmlbeans/trunk/src/main/java/org/apache/xmlbeans/impl/schema/SchemaTypeCodePrinter.java
xmlbeans/trunk/src/main/java/org/apache/xmlbeans/impl/tool/MavenPlugin.java
xmlbeans/trunk/src/main/java/org/apache/xmlbeans/impl/tool/Parameters.java
xmlbeans/trunk/src/main/java/org/apache/xmlbeans/impl/tool/SchemaCompiler.java
xmlbeans/trunk/src/main/resources/maven/plugin.xml
xmlbeans/trunk/src/test/java/compile/scomp/checkin/CompilationTests.java
Modified: xmlbeans/trunk/src/main/java/org/apache/xmlbeans/XmlOptions.java
URL: http://svn.apache.org/viewvc/xmlbeans/trunk/src/main/java/org/apache/xmlbeans/XmlOptions.java?rev=1890934&r1=1890933&r2=1890934&view=diff
==============================================================================
--- xmlbeans/trunk/src/main/java/org/apache/xmlbeans/XmlOptions.java (original)
+++ xmlbeans/trunk/src/main/java/org/apache/xmlbeans/XmlOptions.java Sun Jun 20 21:41:08 2021
@@ -134,6 +134,7 @@ public class XmlOptions implements java.
COMPILE_MDEF_NAMESPACES,
COMPILE_PARTIAL_TYPESYSTEM,
COMPILE_PARTIAL_METHODS,
+ COMPILE_ANNOTATION_JAVADOC,
VALIDATE_ON_SET,
VALIDATE_TREAT_LAX_AS_SKIP,
VALIDATE_STRICT,
@@ -1369,6 +1370,7 @@ public class XmlOptions implements java.
return flag != null && flag;
}
+
public XmlOptions setXPathUseXmlBeans() {
return setXPathUseSaxon(true);
}
@@ -1382,6 +1384,26 @@ public class XmlOptions implements java.
return flag != null && flag;
}
+ public XmlOptions setCompileAnnotationAsJavadoc() {
+ return setCompileAnnotationAsJavadoc(true);
+ }
+
+ /**
+ * When generating the schema sources, copy over the schema annotations to the javadoc.
+ * Be aware basic code injection is filtered, but annotation based RCE aren't filtered.
+ * So think twice before activating this on untrusted schemas!
+ *
+ * @param useAnnotationAsJavadoc {@code true} = copy the annotation - defaults to {@code false}
+ */
+ public XmlOptions setCompileAnnotationAsJavadoc(boolean useAnnotationAsJavadoc) {
+ return set(XmlOptionsKeys.COMPILE_ANNOTATION_JAVADOC, useAnnotationAsJavadoc);
+ }
+
+ public boolean isCompileAnnotationAsJavadoc() {
+ Boolean flag = (Boolean) get(XmlOptionsKeys.COMPILE_ANNOTATION_JAVADOC);
+ return flag != null && flag;
+ }
+
public XmlOptions setAttributeValidationCompatMode(boolean attributeValidationCompatMode) {
return set(XmlOptionsKeys.ATTTRIBUTE_VALIDATION_COMPAT_MODE, attributeValidationCompatMode);
}
Modified: xmlbeans/trunk/src/main/java/org/apache/xmlbeans/impl/schema/SchemaTypeCodePrinter.java
URL: http://svn.apache.org/viewvc/xmlbeans/trunk/src/main/java/org/apache/xmlbeans/impl/schema/SchemaTypeCodePrinter.java?rev=1890934&r1=1890933&r2=1890934&view=diff
==============================================================================
--- xmlbeans/trunk/src/main/java/org/apache/xmlbeans/impl/schema/SchemaTypeCodePrinter.java (original)
+++ xmlbeans/trunk/src/main/java/org/apache/xmlbeans/impl/schema/SchemaTypeCodePrinter.java Sun Jun 20 21:41:08 2021
@@ -185,7 +185,7 @@ public final class SchemaTypeCodePrinter
}
emit("/**");
- if(sType.getDocumentation() != null && sType.getDocumentation().length() > 0){
+ if (opt.isCompileAnnotationAsJavadoc() && sType.getDocumentation() != null && sType.getDocumentation().length() > 0){
emit(" *");
printJavaDocBody(sType.getDocumentation());
emit(" *");
@@ -500,29 +500,15 @@ public final class SchemaTypeCodePrinter
emit(" */");
}
- // removes newline, tabs and white spaces.
- String cleanUpString(String s){
- s = s.replace("\n", "");
- s = s.replace("\t", "");
- return s.trim();
- }
-
- void printJavaDocBody(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("*/", "* /");
- int start = 0;
- int newLineIndex = s.indexOf("\n");
-
- if(newLineIndex == -1){
+ for (String s : docClean.split("[\\n\\r]+")) {
emit(" * " + s);
- }else{
- if(newLineIndex == 0){
- newLineIndex = s.indexOf("\n", newLineIndex + 1);
- }
- while(newLineIndex > 0){
- emit(" * " + cleanUpString(s.substring(start, newLineIndex)));
- start = newLineIndex;
- newLineIndex = s.indexOf("\n", start + 1);
- }
}
}
@@ -810,7 +796,7 @@ public final class SchemaTypeCodePrinter
boolean xmltype = (javaType == SchemaProperty.XML_OBJECT);
if (prop.extendsJavaSingleton()) {
- if(propertyDocumentation != null && propertyDocumentation.length() > 0){
+ if (opt.isCompileAnnotationAsJavadoc() && propertyDocumentation != null && propertyDocumentation.length() > 0){
printJavaDocParagraph(propertyDocumentation);
}else {
printJavaDoc((several ? "Gets first " : "Gets the ") + propdesc, BeanMethod.GET);
@@ -829,7 +815,7 @@ public final class SchemaTypeCodePrinter
}
if (prop.extendsJavaOption()) {
- if(propertyDocumentation != null && propertyDocumentation.length() > 0){
+ if (opt.isCompileAnnotationAsJavadoc() && propertyDocumentation != null && propertyDocumentation.length() > 0){
printJavaDocParagraph(propertyDocumentation);
}else {
printJavaDoc((several ? "True if has at least one " : "True if has ") + propdesc, BeanMethod.IS_SET);
@@ -838,7 +824,7 @@ public final class SchemaTypeCodePrinter
}
if (several) {
- if(propertyDocumentation != null && propertyDocumentation.length() > 0){
+ if (opt.isCompileAnnotationAsJavadoc() && propertyDocumentation != null && propertyDocumentation.length() > 0){
printJavaDocParagraph(propertyDocumentation);
}
@@ -849,14 +835,14 @@ public final class SchemaTypeCodePrinter
wrappedType = javaWrappedType(javaType);
}
- if(propertyDocumentation != null && propertyDocumentation.length() > 0){
+ if (opt.isCompileAnnotationAsJavadoc() && propertyDocumentation != null && propertyDocumentation.length() > 0){
printJavaDocParagraph(propertyDocumentation);
}else{
printJavaDoc("Gets a List of " + propdesc + "s", BeanMethod.GET_LIST);
}
emit("java.util.List<" + wrappedType + "> get" + propertyName + "List();", BeanMethod.GET_LIST);
- if(propertyDocumentation != null && propertyDocumentation.length() > 0){
+ if (opt.isCompileAnnotationAsJavadoc() && propertyDocumentation != null && propertyDocumentation.length() > 0){
printJavaDocParagraph(propertyDocumentation);
}else{
printJavaDoc("Gets array of all " + propdesc + "s", BeanMethod.GET_ARRAY);
@@ -909,7 +895,7 @@ public final class SchemaTypeCodePrinter
String propdesc = "\"" + qName.getLocalPart() + "\"" + (isAttr ? " attribute" : " element");
if (singleton) {
- if(propertyDocumentation != null && propertyDocumentation.length() > 0) {
+ if (opt.isCompileAnnotationAsJavadoc() && propertyDocumentation != null && propertyDocumentation.length() > 0) {
printJavaDocParagraph(propertyDocumentation);
} else {
printJavaDoc((several ? "Sets first " : "Sets the ") + propdesc, BeanMethod.SET);
@@ -933,7 +919,7 @@ public final class SchemaTypeCodePrinter
}
if (optional) {
- if(propertyDocumentation != null && propertyDocumentation.length() > 0) {
+ if (opt.isCompileAnnotationAsJavadoc() && propertyDocumentation != null && propertyDocumentation.length() > 0) {
printJavaDocParagraph(propertyDocumentation);
} else {
printJavaDoc((several ? "Removes first " : "Unsets the ") + propdesc, BeanMethod.UNSET);
@@ -944,14 +930,14 @@ public final class SchemaTypeCodePrinter
if (several) {
String arrayName = propertyName + "Array";
- if(propertyDocumentation != null && propertyDocumentation.length() > 0) {
+ if(opt.isCompileAnnotationAsJavadoc() && propertyDocumentation != null && propertyDocumentation.length() > 0) {
printJavaDocParagraph(propertyDocumentation);
} else {
printJavaDoc("Sets array of all " + propdesc, BeanMethod.SET_ARRAY);
}
emit("void set" + arrayName + "(" + type + "[] " + safeVarName + "Array);", BeanMethod.SET_ARRAY);
- if(propertyDocumentation != null && propertyDocumentation.length() > 0) {
+ if (opt.isCompileAnnotationAsJavadoc() && propertyDocumentation != null && propertyDocumentation.length() > 0) {
printJavaDocParagraph(propertyDocumentation);
} else {
printJavaDoc("Sets ith " + propdesc, BeanMethod.SET_IDX);
@@ -1675,7 +1661,7 @@ public final class SchemaTypeCodePrinter
if (prop.extendsJavaSingleton()) {
if (bmList == null || bmList.contains(BeanMethod.GET)) {
// Value getProp()
- if(propertyDocumentation != null && propertyDocumentation.length() > 0){
+ if(opt.isCompileAnnotationAsJavadoc() && propertyDocumentation != null && propertyDocumentation.length() > 0){
printJavaDocParagraph(propertyDocumentation);
} else {
printJavaDoc((several ? "Gets first " : "Gets the ") + propdesc);
Modified: xmlbeans/trunk/src/main/java/org/apache/xmlbeans/impl/tool/MavenPlugin.java
URL: http://svn.apache.org/viewvc/xmlbeans/trunk/src/main/java/org/apache/xmlbeans/impl/tool/MavenPlugin.java?rev=1890934&r1=1890933&r2=1890934&view=diff
==============================================================================
--- xmlbeans/trunk/src/main/java/org/apache/xmlbeans/impl/tool/MavenPlugin.java (original)
+++ xmlbeans/trunk/src/main/java/org/apache/xmlbeans/impl/tool/MavenPlugin.java Sun Jun 20 21:41:08 2021
@@ -172,6 +172,10 @@ public class MavenPlugin extends Abstrac
@Parameter( defaultValue = "false" )
private boolean debug;
+ /** copy annotations to javadoc of generated sources - default: false */
+ @Parameter( defaultValue = "false" )
+ private boolean copyAnn;
+
@Parameter
private List<Extension> extensions;
@@ -269,6 +273,7 @@ public class MavenPlugin extends Abstrac
params.setNoUpa(noUpa);
params.setNoPvr(noPvr);
params.setNoAnn(noAnn);
+ params.setCopyAnn(copyAnn);
params.setNoVDoc(noVDoc);
if (repackage != null && !repackage.isEmpty()) {
params.setRepackage("org.apache.xmlbeans.metadata:"+repackage);
Modified: xmlbeans/trunk/src/main/java/org/apache/xmlbeans/impl/tool/Parameters.java
URL: http://svn.apache.org/viewvc/xmlbeans/trunk/src/main/java/org/apache/xmlbeans/impl/tool/Parameters.java?rev=1890934&r1=1890933&r2=1890934&view=diff
==============================================================================
--- xmlbeans/trunk/src/main/java/org/apache/xmlbeans/impl/tool/Parameters.java (original)
+++ xmlbeans/trunk/src/main/java/org/apache/xmlbeans/impl/tool/Parameters.java Sun Jun 20 21:41:08 2021
@@ -53,6 +53,7 @@ public class Parameters {
private boolean noVDoc;
private boolean noExt;
private boolean debug;
+ private boolean copyAnn;
private boolean incrementalSrcGen;
private String repackage;
private List<Extension> extensions = Collections.emptyList();
@@ -278,6 +279,14 @@ public class Parameters {
repackage = newRepackage;
}
+ public boolean isCopyAnn() {
+ return copyAnn;
+ }
+
+ public void setCopyAnn(boolean newCopyAnn) {
+ copyAnn = newCopyAnn;
+ }
+
public List<Extension> getExtensions() {
return extensions;
}
Modified: xmlbeans/trunk/src/main/java/org/apache/xmlbeans/impl/tool/SchemaCompiler.java
URL: http://svn.apache.org/viewvc/xmlbeans/trunk/src/main/java/org/apache/xmlbeans/impl/tool/SchemaCompiler.java?rev=1890934&r1=1890933&r2=1890934&view=diff
==============================================================================
--- xmlbeans/trunk/src/main/java/org/apache/xmlbeans/impl/tool/SchemaCompiler.java (original)
+++ xmlbeans/trunk/src/main/java/org/apache/xmlbeans/impl/tool/SchemaCompiler.java Sun Jun 20 21:41:08 2021
@@ -66,6 +66,7 @@ public class SchemaCompiler {
System.out.println(" -partialMethods [list] - comma separated list of bean methods to be generated. Use \"-\" to negate and \"ALL\" for all." );
System.out.println(" processed left-to-right, e.g. \"ALL,-GET_LIST\" exclude java.util.List getters - see XmlOptions.BeanMethod" );
System.out.println(" -repackage - repackage specification, e.g. \"org.apache.xmlbeans.metadata:mypackage.metadata\" to change the metadata directory");
+ System.out.println(" -copyann - copy schema annotations to javadoc (default false) - don't activate on untrusted schema sources!");
/* Undocumented feature - pass in one schema compiler extension and related parameters
System.out.println(" -extension - registers a schema compiler extension");
System.out.println(" -extensionParms - specify parameters for the compiler extension");
@@ -115,6 +116,7 @@ public class SchemaCompiler {
opts.add("allowmdef");
opts.add("catalog");
opts.add("partialMethods");
+ opts.add("copyann");
CommandLine cl = new CommandLine(args, flags, opts);
@@ -183,6 +185,7 @@ public class SchemaCompiler {
boolean noExt = (cl.getOpt("noext") != null);
boolean nojavac = (cl.getOpt("srconly") != null);
boolean debug = (cl.getOpt("debug") != null);
+ boolean copyAnn = (cl.getOpt("copyann") != null);
String allowmdef = cl.getOpt("allowmdef");
Set<String> mdefNamespaces = (allowmdef == null ? Collections.emptySet() :
@@ -337,6 +340,7 @@ public class SchemaCompiler {
params.setCatalogFile(catString);
params.setSchemaCodePrinter(codePrinter);
params.setPartialMethods(parsePartialMethods(partialMethods));
+ params.setCopyAnn(copyAnn);
boolean result = compile(params);
if (tempdir != null) {
@@ -609,6 +613,7 @@ public class SchemaCompiler {
boolean noVDoc = params.isNoVDoc();
boolean noExt = params.isNoExt();
boolean incrSrcGen = params.isIncrementalSrcGen();
+ boolean copyAnn = params.isCopyAnn();
Collection<XmlError> outerErrorListener = params.getErrorListener();
Set<BeanMethod> partialMethods = params.getPartialMethods();
@@ -687,6 +692,7 @@ public class SchemaCompiler {
}
options.setCompilePartialMethod(partialMethods);
options.setCompileNoAnnotations(noAnn);
+ options.setCompileAnnotationAsJavadoc(copyAnn);
// save .xsb files
system.save(filer);
Modified: xmlbeans/trunk/src/main/resources/maven/plugin.xml
URL: http://svn.apache.org/viewvc/xmlbeans/trunk/src/main/resources/maven/plugin.xml?rev=1890934&r1=1890933&r2=1890934&view=diff
==============================================================================
--- xmlbeans/trunk/src/main/resources/maven/plugin.xml (original)
+++ xmlbeans/trunk/src/main/resources/maven/plugin.xml Sun Jun 20 21:41:08 2021
@@ -343,6 +343,13 @@
</extensions>
]]></description>
</parameter>
+ <parameter>
+ <name>copyAnn</name>
+ <type>boolean</type>
+ <required>false</required>
+ <editable>true</editable>
+ <description>copy annotation to javadoc of generated source - don't use on untrusted schemas/sources!</description>
+ </parameter>
</parameters>
<configuration>
<project implementation="org.apache.maven.project.MavenProject" default-value="${project}"/>
@@ -360,6 +367,7 @@
<noUpa implementation="boolean" default-value="false"/>
<noPvr implementation="boolean" default-value="false"/>
<noAnn implementation="boolean" default-value="false"/>
+ <copyAnn implementation="boolean" default-value="false"/>
<noVDoc implementation="boolean" default-value="false"/>
<download implementation="boolean" default-value="false"/>
<debug implementation="boolean" default-value="false"/>
Modified: xmlbeans/trunk/src/test/java/compile/scomp/checkin/CompilationTests.java
URL: http://svn.apache.org/viewvc/xmlbeans/trunk/src/test/java/compile/scomp/checkin/CompilationTests.java?rev=1890934&r1=1890933&r2=1890934&view=diff
==============================================================================
--- xmlbeans/trunk/src/test/java/compile/scomp/checkin/CompilationTests.java (original)
+++ xmlbeans/trunk/src/test/java/compile/scomp/checkin/CompilationTests.java Sun Jun 20 21:41:08 2021
@@ -432,6 +432,30 @@ public class CompilationTests {
}
}
+ @Test
+ public void annotation2javadoc() throws Exception {
+ deltree(xbeanOutput("compile/scomp/javadoc"));
+ File srcdir = xbeanOutput("compile/scomp/javadoc/src");
+ File classesdir = xbeanOutput("compile/scomp/javadoc/classes");
+ File outputjar = xbeanOutput("compile/scomp/javadoc/javadoc.jar");
+ Parameters params = new Parameters();
+ params.setXsdFiles(xbeanCase("schemacompiler/javadoc.xsd"));
+ params.setSrcDir(srcdir);
+ params.setClassesDir(classesdir);
+ params.setOutputJar(outputjar);
+ params.setName("javadoc");
+ SchemaCompiler.compile(params);
+
+ Path p = new File(srcdir, "javadoc/RootDocument.java").toPath();
+ String act = new String(Files.readAllBytes(p), StandardCharsets.UTF_8);
+ assertFalse(act.contains("* / heck, I'm smart"));
+
+ params.setCopyAnn(true);
+ SchemaCompiler.compile(params);
+
+ act = new String(Files.readAllBytes(p), StandardCharsets.UTF_8);
+ assertTrue(act.contains("* / heck, I'm smart"));
+ }
//TESTENV:
Copied: xmlbeans/trunk/src/test/resources/xbean/compile/scomp/schemacompiler/javadoc.xsd (from r1890294, xmlbeans/trunk/src/test/resources/xbean/compile/scomp/partials/partialMethods.xsd)
URL: http://svn.apache.org/viewvc/xmlbeans/trunk/src/test/resources/xbean/compile/scomp/schemacompiler/javadoc.xsd?p2=xmlbeans/trunk/src/test/resources/xbean/compile/scomp/schemacompiler/javadoc.xsd&p1=xmlbeans/trunk/src/test/resources/xbean/compile/scomp/partials/partialMethods.xsd&r1=1890294&r2=1890934&rev=1890934&view=diff
==============================================================================
--- xmlbeans/trunk/src/test/resources/xbean/compile/scomp/partials/partialMethods.xsd (original)
+++ xmlbeans/trunk/src/test/resources/xbean/compile/scomp/schemacompiler/javadoc.xsd Sun Jun 20 21:41:08 2021
@@ -13,24 +13,27 @@
See the License for the specific language governing permissions and
limitations under the License. -->
-
+<!DOCTYPE xs:schema [
+ <!ENTITY endcom "*/" >
+ <!ENTITY cve "*/ heck, I'm smart */ &endcom;" >
+]>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
- xmlns="partials"
- targetNamespace="partials"
+ xmlns="javadoc"
+ targetNamespace="javadoc"
elementFormDefault="qualified">
<xs:element name="root">
<xs:complexType>
<xs:sequence>
- <xs:element name="single" minOccurs="0" type="xs:decimal" nillable="true"/>
- <xs:element name="complex" minOccurs="0" type="xmlBeanchen"/>
- <xs:element name="primitiveList" minOccurs="0" maxOccurs="unbounded" type="xs:decimal" nillable="true"/>
- <xs:element name="complexList" minOccurs="0" maxOccurs="unbounded" type="xmlBeanchen"/>
+ <xs:element name="single" minOccurs="0" type="xs:decimal" nillable="true">
+ <xs:annotation>
+ <xs:documentation>@deprecated use something else
+ */ just try to inject code
+ &cve;
+ </xs:documentation>
+ </xs:annotation>
+ </xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
-
- <xs:complexType name="xmlBeanchen">
- <xs:attribute name="name" type="xs:string"/>
- </xs:complexType>
</xs:schema>
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@poi.apache.org
For additional commands, e-mail: commits-help@poi.apache.org