Index: jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/xml/DavDocumentBuilderFactory.java
===================================================================
--- jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/xml/DavDocumentBuilderFactory.java (revision 0)
+++ jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/xml/DavDocumentBuilderFactory.java (working copy)
@@ -0,0 +1,86 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.webdav.xml;
+
+import java.io.IOException;
+
+import javax.xml.XMLConstants;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.xml.sax.EntityResolver;
+import org.xml.sax.InputSource;
+import org.xml.sax.helpers.DefaultHandler;
+
+/**
+ * Custom {@link DocumentBuilderFactory} extended for use in WebDAV.
+ */
+public class DavDocumentBuilderFactory {
+
+ private static final Logger LOG = LoggerFactory.getLogger(DomUtil.class);
+
+ private final DocumentBuilderFactory DEFAULT_FACTORY = createFactory();
+
+ private DocumentBuilderFactory BUILDER_FACTORY = DEFAULT_FACTORY;
+
+ private DocumentBuilderFactory createFactory() {
+ DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+ factory.setNamespaceAware(true);
+ factory.setIgnoringComments(true);
+ factory.setIgnoringElementContentWhitespace(true);
+ factory.setCoalescing(true);
+ try {
+ factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
+ } catch (ParserConfigurationException e) {
+ LOG.warn("Secure XML processing is not supported", e);
+ } catch (AbstractMethodError e) {
+ LOG.warn("Secure XML processing is not supported", e);
+ }
+ return factory;
+ }
+
+ public void setFactory(DocumentBuilderFactory documentBuilderFactory) {
+ LOG.debug("DocumentBuilderFactory changed to: " + documentBuilderFactory);
+ BUILDER_FACTORY = documentBuilderFactory != null ? documentBuilderFactory : DEFAULT_FACTORY;
+ }
+
+ /**
+ * An entity resolver that does not allow external entity resolution. See
+ * RFC 4918, Section 20.6
+ */
+ private static final EntityResolver DEFAULT_ENTITY_RESOLVER = new EntityResolver() {
+ public InputSource resolveEntity(String publicId, String systemId) throws IOException {
+ LOG.debug("Resolution of external entities in XML payload not supported - publicId: " + publicId + ", systemId: "
+ + systemId);
+ throw new IOException("This parser does not support resolution of external entities (publicId: " + publicId
+ + ", systemId: " + systemId + ")");
+ }
+ };
+
+ public DocumentBuilder newDocumentBuilder() throws ParserConfigurationException {
+ DocumentBuilder db = BUILDER_FACTORY.newDocumentBuilder();
+ if (BUILDER_FACTORY == DEFAULT_FACTORY) {
+ // if this is the default factory: set the default entity resolver as well
+ db.setEntityResolver(DEFAULT_ENTITY_RESOLVER);
+ }
+ db.setErrorHandler(new DefaultHandler());
+ return db;
+ }
+}
Index: jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/xml/DomUtil.java
===================================================================
--- jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/xml/DomUtil.java (revision 1678321)
+++ jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/xml/DomUtil.java (working copy)
@@ -30,7 +30,6 @@
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
-import javax.xml.XMLConstants;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
@@ -48,27 +47,11 @@
private static Logger log = LoggerFactory.getLogger(DomUtil.class);
/**
- * Constant for DocumentBuilderFactory
which is used
+ * Constant for DavDocumentBuilderFactory
which is used
* to create and parse DOM documents.
*/
- private static DocumentBuilderFactory BUILDER_FACTORY = createFactory();
+ private static DavDocumentBuilderFactory BUILDER_FACTORY = new DavDocumentBuilderFactory();
- private static DocumentBuilderFactory createFactory() {
- DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
- factory.setNamespaceAware(true);
- factory.setIgnoringComments(true);
- factory.setIgnoringElementContentWhitespace(true);
- factory.setCoalescing(true);
- try {
- factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
- } catch (ParserConfigurationException e) {
- log.warn("Secure XML processing is not supported", e);
- } catch (AbstractMethodError e) {
- log.warn("Secure XML processing is not supported", e);
- }
- return factory;
- }
-
/**
* Support the replacement of {@link #BUILDER_FACTORY}. This is useful
* for injecting a customized BuilderFactory, for example with one that
@@ -80,7 +63,7 @@
*/
public static void setBuilderFactory(
DocumentBuilderFactory documentBuilderFactory) {
- BUILDER_FACTORY = documentBuilderFactory;
+ BUILDER_FACTORY.setFactory(documentBuilderFactory);
}
/**
Index: jackrabbit-webdav/src/test/java/org/apache/jackrabbit/webdav/xml/ParserTest.java
===================================================================
--- jackrabbit-webdav/src/test/java/org/apache/jackrabbit/webdav/xml/ParserTest.java (revision 0)
+++ jackrabbit-webdav/src/test/java/org/apache/jackrabbit/webdav/xml/ParserTest.java (working copy)
@@ -0,0 +1,78 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the \"License\"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an \"AS IS\" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.webdav.xml;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.UnsupportedEncodingException;
+
+import junit.framework.TestCase;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+public class ParserTest extends TestCase {
+
+ // see
+ public void testBillionLaughs() throws UnsupportedEncodingException {
+
+ String testBody = "" + "" + " "
+ + " "
+ + " "
+ + " "
+ + " "
+ + " "
+ + " "
+ + " "
+ + " "
+ + " " + "]>" + "&lol9;";
+ InputStream is = new ByteArrayInputStream(testBody.getBytes("UTF-8"));
+
+ try {
+ DomUtil.parseDocument(is);
+ fail("parsing this document should cause an exception");
+ } catch (Exception expected) {
+ }
+ }
+
+ public void testExternalEntities() throws IOException {
+
+ String dname = "target";
+ String fname = "test.xml";
+
+ File f = new File(dname, fname);
+ OutputStream os = new FileOutputStream(f);
+ os.write("testdata".getBytes());
+ os.close();
+
+ String testBody = "\n"
+ + "]>\n&test;";
+ InputStream is = new ByteArrayInputStream(testBody.getBytes("UTF-8"));
+
+ try {
+ Document d = DomUtil.parseDocument(is);
+ Element root = d.getDocumentElement();
+ String text = DomUtil.getText(root);
+ fail("parsing this document should cause an exception, but the following external content was included: " + text);
+ } catch (Exception expected) {
+ }
+ }
+}
\ No newline at end of file
Index: jackrabbit-webdav/src/test/java/org/apache/jackrabbit/webdav/xml/TestAll.java
===================================================================
--- jackrabbit-webdav/src/test/java/org/apache/jackrabbit/webdav/xml/TestAll.java (revision 1678321)
+++ jackrabbit-webdav/src/test/java/org/apache/jackrabbit/webdav/xml/TestAll.java (working copy)
@@ -33,6 +33,7 @@
TestSuite suite = new TestSuite("org.apache.jackrabbit.webdav.xml tests");
suite.addTestSuite(NamespaceTest.class);
+ suite.addTestSuite(ParserTest.class);
return suite;
}