485 lines
20 KiB
Diff
485 lines
20 KiB
Diff
|
From a8228522a99a02146106672a34c104adbda5c658 Mon Sep 17 00:00:00 2001
|
||
|
From: =?UTF-8?q?Filip=20Jirs=C3=A1k?= <filip@jirsak.org>
|
||
|
Date: Sat, 11 Apr 2020 19:06:44 +0200
|
||
|
Subject: [PATCH] SAXReader uses system default XMLReader with its defaults.
|
||
|
New factory method SAXReader.createDefault() sets more secure defaults.
|
||
|
|
||
|
---
|
||
|
src/java/org/dom4j/DocumentHelper.java | 65 +-
|
||
|
src/java/org/dom4j/io/SAXHelper.java | 37 +-
|
||
|
src/java/org/dom4j/io/SAXReader.java | 1824 ++++++++++---------
|
||
|
3 files changed, 973 insertions(+), 953 deletions(-)
|
||
|
|
||
|
Index: dom4j/src/java/org/dom4j/io/SAXHelper.java
|
||
|
===================================================================
|
||
|
--- dom4j.orig/src/java/org/dom4j/io/SAXHelper.java
|
||
|
+++ dom4j/src/java/org/dom4j/io/SAXHelper.java
|
||
|
@@ -13,6 +13,8 @@ import org.xml.sax.SAXNotSupportedExcept
|
||
|
import org.xml.sax.XMLReader;
|
||
|
import org.xml.sax.helpers.XMLReaderFactory;
|
||
|
|
||
|
+import javax.xml.parsers.SAXParserFactory;
|
||
|
+
|
||
|
/**
|
||
|
* <p>
|
||
|
* <code>SAXHelper</code> contains some helper methods for working with SAX
|
||
|
@@ -59,9 +61,18 @@ class SAXHelper {
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
- * Creats a default XMLReader via the org.xml.sax.driver system property or
|
||
|
+ * Creates a default XMLReader via the org.xml.sax.driver system property or
|
||
|
* JAXP if the system property is not set.
|
||
|
*
|
||
|
+ * This method internally calls {@link SAXParserFactory}{@code .newInstance().newSAXParser().getXMLReader()} or {@link XMLReaderFactory#createXMLReader()}.
|
||
|
+ * Be sure to configure returned reader if the default configuration does not suit you. Consider setting the following properties:
|
||
|
+ *
|
||
|
+ * <pre>
|
||
|
+ * reader.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
|
||
|
+ * reader.setFeature("http://xml.org/sax/features/external-general-entities", false);
|
||
|
+ * reader.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
|
||
|
+ * </pre>
|
||
|
+ *
|
||
|
* @param validating
|
||
|
* DOCUMENT ME!
|
||
|
*
|
||
|
Index: dom4j/src/java/org/dom4j/io/SAXReader.java
|
||
|
===================================================================
|
||
|
--- dom4j.orig/src/java/org/dom4j/io/SAXReader.java
|
||
|
+++ dom4j/src/java/org/dom4j/io/SAXReader.java
|
||
|
@@ -30,6 +30,8 @@ import org.xml.sax.XMLReader;
|
||
|
import org.xml.sax.helpers.DefaultHandler;
|
||
|
import org.xml.sax.helpers.XMLReaderFactory;
|
||
|
|
||
|
+import javax.xml.parsers.SAXParserFactory;
|
||
|
+
|
||
|
/**
|
||
|
* <p>
|
||
|
* <code>SAXReader</code> creates a DOM4J tree from SAX parsing events.
|
||
|
@@ -135,17 +137,76 @@ public class SAXReader {
|
||
|
/** The SAX filter used to filter SAX events */
|
||
|
private XMLFilter xmlFilter;
|
||
|
|
||
|
+ public static SAXReader createDefault() {
|
||
|
+ SAXReader reader = new SAXReader();
|
||
|
+ try {
|
||
|
+ reader.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
|
||
|
+ reader.setFeature("http://xml.org/sax/features/external-general-entities", false);
|
||
|
+ reader.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
|
||
|
+ } catch (SAXException e) {
|
||
|
+ // nothing to do, incompatible reader
|
||
|
+ }
|
||
|
+ return reader;
|
||
|
+ }
|
||
|
+
|
||
|
+ /**
|
||
|
+ * This method internally calls {@link SAXParserFactory}{@code .newInstance().newSAXParser().getXMLReader()} or {@link XMLReaderFactory#createXMLReader()}.
|
||
|
+ * Be sure to configure returned reader if the default configuration does not suit you. Consider setting the following properties:
|
||
|
+ *
|
||
|
+ * <pre>
|
||
|
+ * reader.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
|
||
|
+ * reader.setFeature("http://xml.org/sax/features/external-general-entities", false);
|
||
|
+ * reader.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
|
||
|
+ * </pre>
|
||
|
+ */
|
||
|
public SAXReader() {
|
||
|
}
|
||
|
|
||
|
+ /**
|
||
|
+ * This method internally calls {@link SAXParserFactory}{@code .newInstance().newSAXParser().getXMLReader()} or {@link XMLReaderFactory#createXMLReader()}.
|
||
|
+ * Be sure to configure returned reader if the default configuration does not suit you. Consider setting the following properties:
|
||
|
+ *
|
||
|
+ * <pre>
|
||
|
+ * reader.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
|
||
|
+ * reader.setFeature("http://xml.org/sax/features/external-general-entities", false);
|
||
|
+ * reader.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
|
||
|
+ * </pre>
|
||
|
+ *
|
||
|
+ * @param validating
|
||
|
+ */
|
||
|
public SAXReader(boolean validating) {
|
||
|
this.validating = validating;
|
||
|
}
|
||
|
|
||
|
+ /**
|
||
|
+ * This method internally calls {@link SAXParserFactory}{@code .newInstance().newSAXParser().getXMLReader()} or {@link XMLReaderFactory#createXMLReader()}.
|
||
|
+ * Be sure to configure returned reader if the default configuration does not suit you. Consider setting the following properties:
|
||
|
+ *
|
||
|
+ * <pre>
|
||
|
+ * reader.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
|
||
|
+ * reader.setFeature("http://xml.org/sax/features/external-general-entities", false);
|
||
|
+ * reader.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
|
||
|
+ * </pre>
|
||
|
+ *
|
||
|
+ * @param factory
|
||
|
+ */
|
||
|
public SAXReader(DocumentFactory factory) {
|
||
|
this.factory = factory;
|
||
|
}
|
||
|
|
||
|
+ /**
|
||
|
+ * This method internally calls {@link SAXParserFactory}{@code .newInstance().newSAXParser().getXMLReader()} or {@link XMLReaderFactory#createXMLReader()}.
|
||
|
+ * Be sure to configure returned reader if the default configuration does not suit you. Consider setting the following properties:
|
||
|
+ *
|
||
|
+ * <pre>
|
||
|
+ * reader.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
|
||
|
+ * reader.setFeature("http://xml.org/sax/features/external-general-entities", false);
|
||
|
+ * reader.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
|
||
|
+ * </pre>
|
||
|
+ *
|
||
|
+ * @param factory
|
||
|
+ * @param validating
|
||
|
+ */
|
||
|
public SAXReader(DocumentFactory factory, boolean validating) {
|
||
|
this.factory = factory;
|
||
|
this.validating = validating;
|
||
|
@@ -185,14 +246,10 @@ public class SAXReader {
|
||
|
* this method is to correctly configure an XMLReader object instance and
|
||
|
* call the {@link #setXMLReader(XMLReader)}method
|
||
|
*
|
||
|
- * @param name
|
||
|
- * is the SAX property name
|
||
|
- * @param value
|
||
|
- * is the value of the SAX property
|
||
|
- *
|
||
|
- * @throws SAXException
|
||
|
- * if the XMLReader could not be created or the property could
|
||
|
- * not be changed.
|
||
|
+ * @param name is the SAX property name
|
||
|
+ * @param value is the value of the SAX property
|
||
|
+ * @throws SAXException if the XMLReader could not be created or the property could
|
||
|
+ * not be changed.
|
||
|
*/
|
||
|
public void setProperty(String name, Object value) throws SAXException {
|
||
|
getXMLReader().setProperty(name, value);
|
||
|
@@ -205,14 +262,10 @@ public class SAXReader {
|
||
|
* calling this method is to correctly configure an XMLReader object
|
||
|
* instance and call the {@link #setXMLReader(XMLReader)}method
|
||
|
*
|
||
|
- * @param name
|
||
|
- * is the SAX feature name
|
||
|
- * @param value
|
||
|
- * is the value of the SAX feature
|
||
|
- *
|
||
|
- * @throws SAXException
|
||
|
- * if the XMLReader could not be created or the feature could
|
||
|
- * not be changed.
|
||
|
+ * @param name is the SAX feature name
|
||
|
+ * @param value is the value of the SAX feature
|
||
|
+ * @throws SAXException if the XMLReader could not be created or the feature could
|
||
|
+ * not be changed.
|
||
|
*/
|
||
|
public void setFeature(String name, boolean value) throws SAXException {
|
||
|
getXMLReader().setFeature(name, value);
|
||
|
@@ -223,13 +276,9 @@ public class SAXReader {
|
||
|
* Reads a Document from the given <code>File</code>
|
||
|
* </p>
|
||
|
*
|
||
|
- * @param file
|
||
|
- * is the <code>File</code> to read from.
|
||
|
- *
|
||
|
+ * @param file is the <code>File</code> to read from.
|
||
|
* @return the newly created Document instance
|
||
|
- *
|
||
|
- * @throws DocumentException
|
||
|
- * if an error occurs during parsing.
|
||
|
+ * @throws DocumentException if an error occurs during parsing.
|
||
|
*/
|
||
|
public Document read(File file) throws DocumentException {
|
||
|
try {
|
||
|
@@ -272,13 +321,9 @@ public class SAXReader {
|
||
|
* Reads a Document from the given <code>URL</code> using SAX
|
||
|
* </p>
|
||
|
*
|
||
|
- * @param url
|
||
|
- * <code>URL</code> to read from.
|
||
|
- *
|
||
|
+ * @param url <code>URL</code> to read from.
|
||
|
* @return the newly created Document instance
|
||
|
- *
|
||
|
- * @throws DocumentException
|
||
|
- * if an error occurs during parsing.
|
||
|
+ * @throws DocumentException if an error occurs during parsing.
|
||
|
*/
|
||
|
public Document read(URL url) throws DocumentException {
|
||
|
String systemID = url.toExternalForm();
|
||
|
@@ -304,13 +349,9 @@ public class SAXReader {
|
||
|
* String} to denote the source of the document.
|
||
|
* </p>
|
||
|
*
|
||
|
- * @param systemId
|
||
|
- * is a URL for a document or a file name.
|
||
|
- *
|
||
|
+ * @param systemId is a URL for a document or a file name.
|
||
|
* @return the newly created Document instance
|
||
|
- *
|
||
|
- * @throws DocumentException
|
||
|
- * if an error occurs during parsing.
|
||
|
+ * @throws DocumentException if an error occurs during parsing.
|
||
|
*/
|
||
|
public Document read(String systemId) throws DocumentException {
|
||
|
InputSource source = new InputSource(systemId);
|
||
|
@@ -326,13 +367,9 @@ public class SAXReader {
|
||
|
* Reads a Document from the given stream using SAX
|
||
|
* </p>
|
||
|
*
|
||
|
- * @param in
|
||
|
- * <code>InputStream</code> to read from.
|
||
|
- *
|
||
|
+ * @param in <code>InputStream</code> to read from.
|
||
|
* @return the newly created Document instance
|
||
|
- *
|
||
|
- * @throws DocumentException
|
||
|
- * if an error occurs during parsing.
|
||
|
+ * @throws DocumentException if an error occurs during parsing.
|
||
|
*/
|
||
|
public Document read(InputStream in) throws DocumentException {
|
||
|
InputSource source = new InputSource(in);
|
||
|
@@ -348,13 +385,9 @@ public class SAXReader {
|
||
|
* Reads a Document from the given <code>Reader</code> using SAX
|
||
|
* </p>
|
||
|
*
|
||
|
- * @param reader
|
||
|
- * is the reader for the input
|
||
|
- *
|
||
|
+ * @param reader is the reader for the input
|
||
|
* @return the newly created Document instance
|
||
|
- *
|
||
|
- * @throws DocumentException
|
||
|
- * if an error occurs during parsing.
|
||
|
+ * @throws DocumentException if an error occurs during parsing.
|
||
|
*/
|
||
|
public Document read(Reader reader) throws DocumentException {
|
||
|
InputSource source = new InputSource(reader);
|
||
|
@@ -370,15 +403,10 @@ public class SAXReader {
|
||
|
* Reads a Document from the given stream using SAX
|
||
|
* </p>
|
||
|
*
|
||
|
- * @param in
|
||
|
- * <code>InputStream</code> to read from.
|
||
|
- * @param systemId
|
||
|
- * is the URI for the input
|
||
|
- *
|
||
|
+ * @param in <code>InputStream</code> to read from.
|
||
|
+ * @param systemId is the URI for the input
|
||
|
* @return the newly created Document instance
|
||
|
- *
|
||
|
- * @throws DocumentException
|
||
|
- * if an error occurs during parsing.
|
||
|
+ * @throws DocumentException if an error occurs during parsing.
|
||
|
*/
|
||
|
public Document read(InputStream in, String systemId)
|
||
|
throws DocumentException {
|
||
|
@@ -396,13 +424,9 @@ public class SAXReader {
|
||
|
* Reads a Document from the given <code>Reader</code> using SAX
|
||
|
* </p>
|
||
|
*
|
||
|
- * @param reader
|
||
|
- * is the reader for the input
|
||
|
- * @param systemId
|
||
|
- * is the URI for the input
|
||
|
- *
|
||
|
+ * @param reader is the reader for the input
|
||
|
+ * @param systemId is the URI for the input
|
||
|
* @return the newly created Document instance
|
||
|
- *
|
||
|
* @throws DocumentException
|
||
|
* if an error occurs during parsing.
|
||
|
*/
|
||
|
@@ -422,13 +446,9 @@ public class SAXReader {
|
||
|
* Reads a Document from the given <code>InputSource</code> using SAX
|
||
|
* </p>
|
||
|
*
|
||
|
- * @param in
|
||
|
- * <code>InputSource</code> to read from.
|
||
|
- *
|
||
|
+ * @param in <code>InputSource</code> to read from.
|
||
|
* @return the newly created Document instance
|
||
|
- *
|
||
|
- * @throws DocumentException
|
||
|
- * if an error occurs during parsing.
|
||
|
+ * @throws DocumentException if an error occurs during parsing.
|
||
|
*/
|
||
|
public Document read(InputSource in) throws DocumentException {
|
||
|
try {
|
||
|
@@ -695,8 +715,7 @@ public class SAXReader {
|
||
|
/**
|
||
|
* Sets the entity resolver used to resolve entities.
|
||
|
*
|
||
|
- * @param entityResolver
|
||
|
- * DOCUMENT ME!
|
||
|
+ * @param entityResolver DOCUMENT ME!
|
||
|
*/
|
||
|
public void setEntityResolver(EntityResolver entityResolver) {
|
||
|
this.entityResolver = entityResolver;
|
||
|
@@ -706,9 +725,7 @@ public class SAXReader {
|
||
|
* DOCUMENT ME!
|
||
|
*
|
||
|
* @return the <code>XMLReader</code> used to parse SAX events
|
||
|
- *
|
||
|
- * @throws SAXException
|
||
|
- * DOCUMENT ME!
|
||
|
+ * @throws SAXException DOCUMENT ME!
|
||
|
*/
|
||
|
public XMLReader getXMLReader() throws SAXException {
|
||
|
if (xmlReader == null) {
|
||
|
@@ -721,8 +738,7 @@ public class SAXReader {
|
||
|
/**
|
||
|
* Sets the <code>XMLReader</code> used to parse SAX events
|
||
|
*
|
||
|
- * @param reader
|
||
|
- * is the <code>XMLReader</code> to parse SAX events
|
||
|
+ * @param reader is the <code>XMLReader</code> to parse SAX events
|
||
|
*/
|
||
|
public void setXMLReader(XMLReader reader) {
|
||
|
this.xmlReader = reader;
|
||
|
@@ -742,8 +758,7 @@ public class SAXReader {
|
||
|
/**
|
||
|
* Sets encoding used for InputSource (null means system default encoding)
|
||
|
*
|
||
|
- * @param encoding
|
||
|
- * is encoding used for InputSource
|
||
|
+ * @param encoding is encoding used for InputSource
|
||
|
*/
|
||
|
public void setEncoding(String encoding) {
|
||
|
this.encoding = encoding;
|
||
|
@@ -753,12 +768,9 @@ public class SAXReader {
|
||
|
* Sets the class name of the <code>XMLReader</code> to be used to parse
|
||
|
* SAX events.
|
||
|
*
|
||
|
- * @param xmlReaderClassName
|
||
|
- * is the class name of the <code>XMLReader</code> to parse SAX
|
||
|
- * events
|
||
|
- *
|
||
|
- * @throws SAXException
|
||
|
- * DOCUMENT ME!
|
||
|
+ * @param xmlReaderClassName is the class name of the <code>XMLReader</code>
|
||
|
+ * to parse SAX events
|
||
|
+ * @throws SAXException DOCUMENT ME!
|
||
|
*/
|
||
|
public void setXMLReaderClassName(String xmlReaderClassName)
|
||
|
throws SAXException {
|
||
|
@@ -769,11 +781,9 @@ public class SAXReader {
|
||
|
* Adds the <code>ElementHandler</code> to be called when the specified
|
||
|
* path is encounted.
|
||
|
*
|
||
|
- * @param path
|
||
|
- * is the path to be handled
|
||
|
- * @param handler
|
||
|
- * is the <code>ElementHandler</code> to be called by the event
|
||
|
- * based processor.
|
||
|
+ * @param path is the path to be handled
|
||
|
+ * @param handler is the <code>ElementHandler</code> to be called by the event
|
||
|
+ * based processor.
|
||
|
*/
|
||
|
public void addHandler(String path, ElementHandler handler) {
|
||
|
getDispatchHandler().addHandler(path, handler);
|
||
|
@@ -783,8 +793,7 @@ public class SAXReader {
|
||
|
* Removes the <code>ElementHandler</code> from the event based processor,
|
||
|
* for the specified path.
|
||
|
*
|
||
|
- * @param path
|
||
|
- * is the path to remove the <code>ElementHandler</code> for.
|
||
|
+ * @param path is the path to remove the <code>ElementHandler</code> for.
|
||
|
*/
|
||
|
public void removeHandler(String path) {
|
||
|
getDispatchHandler().removeHandler(path);
|
||
|
@@ -795,9 +804,8 @@ public class SAXReader {
|
||
|
* registered, this will set a default <code>ElementHandler</code> to be
|
||
|
* called for any path which does <b>NOT </b> have a handler registered.
|
||
|
*
|
||
|
- * @param handler
|
||
|
- * is the <code>ElementHandler</code> to be called by the event
|
||
|
- * based processor.
|
||
|
+ * @param handler is the <code>ElementHandler</code> to be called by the event
|
||
|
+ * based processor.
|
||
|
*/
|
||
|
public void setDefaultHandler(ElementHandler handler) {
|
||
|
getDispatchHandler().setDefaultHandler(handler);
|
||
|
@@ -824,8 +832,7 @@ public class SAXReader {
|
||
|
/**
|
||
|
* Sets the SAX filter to be used when filtering SAX events
|
||
|
*
|
||
|
- * @param filter
|
||
|
- * is the SAX filter to use or null to disable filtering
|
||
|
+ * @param filter is the SAX filter to use or null to disable filtering
|
||
|
*/
|
||
|
public void setXMLFilter(XMLFilter filter) {
|
||
|
this.xmlFilter = filter;
|
||
|
@@ -838,9 +845,7 @@ public class SAXReader {
|
||
|
* Installs any XMLFilter objects required to allow the SAX event stream to
|
||
|
* be filtered and preprocessed before it gets to dom4j.
|
||
|
*
|
||
|
- * @param reader
|
||
|
- * DOCUMENT ME!
|
||
|
- *
|
||
|
+ * @param reader DOCUMENT ME!
|
||
|
* @return the new XMLFilter if applicable or the original XMLReader if no
|
||
|
* filter is being used.
|
||
|
*/
|
||
|
@@ -886,9 +891,7 @@ public class SAXReader {
|
||
|
* XMLReader objects
|
||
|
*
|
||
|
* @return DOCUMENT ME!
|
||
|
- *
|
||
|
- * @throws SAXException
|
||
|
- * DOCUMENT ME!
|
||
|
+ * @throws SAXException DOCUMENT ME!
|
||
|
*/
|
||
|
protected XMLReader createXMLReader() throws SAXException {
|
||
|
return SAXHelper.createXMLReader(isValidating());
|
||
|
@@ -897,13 +900,9 @@ public class SAXReader {
|
||
|
/**
|
||
|
* Configures the XMLReader before use
|
||
|
*
|
||
|
- * @param reader
|
||
|
- * DOCUMENT ME!
|
||
|
- * @param handler
|
||
|
- * DOCUMENT ME!
|
||
|
- *
|
||
|
- * @throws DocumentException
|
||
|
- * DOCUMENT ME!
|
||
|
+ * @param reader DOCUMENT ME!
|
||
|
+ * @param handler DOCUMENT ME!
|
||
|
+ * @throws DocumentException DOCUMENT ME!
|
||
|
*/
|
||
|
protected void configureReader(XMLReader reader, DefaultHandler handler)
|
||
|
throws DocumentException {
|
||
|
@@ -918,10 +917,11 @@ public class SAXReader {
|
||
|
SAXHelper.setParserProperty(reader, SAX_DECL_HANDLER, handler);
|
||
|
}
|
||
|
|
||
|
- // configure namespace support
|
||
|
- SAXHelper.setParserFeature(reader, SAX_NAMESPACES, true);
|
||
|
+ // // configure namespace support
|
||
|
+ // SAXHelper.setParserFeature(reader, SAX_NAMESPACES, true);
|
||
|
|
||
|
- SAXHelper.setParserFeature(reader, SAX_NAMESPACE_PREFIXES, false);
|
||
|
+ // string interning
|
||
|
+ // SAXHelper.setParserFeature(reader, SAX_NAMESPACE_PREFIXES, false);
|
||
|
|
||
|
// string interning
|
||
|
SAXHelper.setParserFeature(reader, SAX_STRING_INTERNING,
|
||
|
@@ -936,8 +936,8 @@ public class SAXReader {
|
||
|
* includeExternalParameterEntities );
|
||
|
*/
|
||
|
// use Locator2 if possible
|
||
|
- SAXHelper.setParserFeature(reader,
|
||
|
- "http://xml.org/sax/features/use-locator2", true);
|
||
|
+ // SAXHelper.setParserFeature(reader,
|
||
|
+ // "http://xml.org/sax/features/use-locator2", true);
|
||
|
|
||
|
try {
|
||
|
// configure validation support
|
||
|
@@ -960,9 +960,7 @@ public class SAXReader {
|
||
|
/**
|
||
|
* Factory Method to allow user derived SAXContentHandler objects to be used
|
||
|
*
|
||
|
- * @param reader
|
||
|
- * DOCUMENT ME!
|
||
|
- *
|
||
|
+ * @param reader DOCUMENT ME!
|
||
|
* @return DOCUMENT ME!
|
||
|
*/
|
||
|
protected SAXContentHandler createContentHandler(XMLReader reader) {
|