Add XMLInputFactory to UntrustedXML 66/57566/2
authorRobert Varga <robert.varga@pantheon.tech>
Fri, 19 May 2017 18:15:27 +0000 (20:15 +0200)
committerRobert Varga <nite@hq.sk>
Sat, 27 May 2017 07:24:30 +0000 (07:24 +0000)
Similar to other ways of accessing XML, this adds a convenience
accessor to XMLInputFactory.

Change-Id: I43f4e0fa2452d13b60e244d03cbf9d68bc391735
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
common/util/src/main/java/org/opendaylight/yangtools/util/xml/UntrustedXML.java

index 39e32b61e7073d35876f23c03ededf37e6b06805..05ef089bdb7ede0a1a577f77f67e13b04b54551b 100644 (file)
@@ -8,6 +8,9 @@
 package org.opendaylight.yangtools.util.xml;
 
 import com.google.common.annotations.Beta;
+import java.io.InputStream;
+import java.io.Reader;
+import java.nio.charset.Charset;
 import javax.annotation.Nonnull;
 import javax.xml.XMLConstants;
 import javax.xml.parsers.DocumentBuilder;
@@ -15,6 +18,9 @@ import javax.xml.parsers.DocumentBuilderFactory;
 import javax.xml.parsers.ParserConfigurationException;
 import javax.xml.parsers.SAXParser;
 import javax.xml.parsers.SAXParserFactory;
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
 import org.xml.sax.SAXException;
 
 /**
@@ -36,6 +42,7 @@ public final class UntrustedXML {
         try {
             f.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
             f.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
+            f.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
             f.setFeature("http://xml.org/sax/features/external-general-entities", false);
             f.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
         } catch (final ParserConfigurationException e) {
@@ -52,6 +59,7 @@ public final class UntrustedXML {
         try {
             f.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
             f.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
+            f.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
             f.setFeature("http://xml.org/sax/features/external-general-entities", false);
             f.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
         } catch (final Exception e) {
@@ -61,6 +69,19 @@ public final class UntrustedXML {
         SPF = f;
     }
 
+    private static final XMLInputFactory XIF;
+    static {
+        final XMLInputFactory f = XMLInputFactory.newInstance();
+
+        f.setProperty(XMLInputFactory.IS_COALESCING, Boolean.TRUE);
+        f.setProperty(XMLInputFactory.IS_NAMESPACE_AWARE, Boolean.TRUE);
+        f.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, Boolean.FALSE);
+        f.setProperty(XMLInputFactory.SUPPORT_DTD, Boolean.FALSE);
+
+        XIF = f;
+    }
+
+
     /**
      * Create a new {@link DocumentBuilder} for dealing with untrusted XML data. This method is equivalent to
      * {@link DocumentBuilderFactory#newDocumentBuilder()}, except it does not throw a checked exception.
@@ -90,4 +111,38 @@ public final class UntrustedXML {
             throw new UnsupportedOperationException("Failed to instantiate a SAXParser", e);
         }
     }
+
+    /**
+     * Create a new {@link XMLStreamReader} for dealing with untrusted XML data. This method is equivalent to
+     * {@link XMLInputFactory#createXMLStreamReader(InputStream)}.
+     *
+     * @return A new XMLStreamReader
+     * @throws XMLStreamException when the underlying factory throws it
+     */
+    public static @Nonnull XMLStreamReader createXMLStreamReader(final InputStream stream) throws XMLStreamException {
+        return XIF.createXMLStreamReader(stream);
+    }
+
+    /**
+     * Create a new {@link XMLStreamReader} for dealing with untrusted XML data. This method is equivalent to
+     * {@link XMLInputFactory#createXMLStreamReader(InputStream, String)}, except it takes an explict charset argument.
+     *
+     * @return A new XMLStreamReader
+     * @throws XMLStreamException when the underlying factory throws it
+     */
+    public static @Nonnull XMLStreamReader createXMLStreamReader(final InputStream stream, final Charset charset)
+            throws XMLStreamException {
+        return XIF.createXMLStreamReader(stream, charset.name());
+    }
+
+    /**
+     * Create a new {@link XMLStreamReader} for dealing with untrusted XML data. This method is equivalent to
+     * {@link XMLInputFactory#createXMLStreamReader(Reader)}.
+     *
+     * @return A new XMLStreamReader
+     * @throws XMLStreamException when the underlying factory throws it
+     */
+    public static @Nonnull XMLStreamReader createXMLStreamReader(final Reader reader) throws XMLStreamException {
+        return XIF.createXMLStreamReader(reader);
+    }
 }