422 lines
17 KiB
Diff
422 lines
17 KiB
Diff
From 80cb805eb1488ba3a16c427866fa8ae1f52ff0c5 Mon Sep 17 00:00:00 2001
|
|
From: PJ Fanning <fanningpj@apache.org>
|
|
Date: Sun, 10 Jun 2018 10:15:30 +0000
|
|
Subject: [PATCH 1/2] use safe XML parsers
|
|
|
|
git-svn-id: https://svn.apache.org/repos/asf/xmlbeans/trunk@1833260 13f79535-47bb-0310-9956-ffa450edef68
|
|
---
|
|
.../xmlbeans/impl/common/DocumentHelper.java | 165 ++++++++++++++++++
|
|
.../xmlbeans/impl/common/LoadSaveUtils.java | 6 +-
|
|
.../xmlbeans/impl/common}/NullLogger.java | 4 +-
|
|
.../xmlbeans/impl/common}/SAXHelper.java | 6 +-
|
|
.../apache/xmlbeans/impl/common/Sax2Dom.java | 9 +-
|
|
.../xmlbeans/impl/common}/XBLogFactory.java | 4 +-
|
|
.../xmlbeans/impl/common}/XBLogger.java | 4 +-
|
|
.../apache/xmlbeans/impl/store/Locale.java | 24 +--
|
|
8 files changed, 189 insertions(+), 33 deletions(-)
|
|
create mode 100644 src/common/org/apache/xmlbeans/impl/common/DocumentHelper.java
|
|
rename src/{store/org/apache/xmlbeans/impl/store => common/org/apache/xmlbeans/impl/common}/NullLogger.java (95%)
|
|
rename src/{store/org/apache/xmlbeans/impl/store => common/org/apache/xmlbeans/impl/common}/SAXHelper.java (96%)
|
|
rename src/{store/org/apache/xmlbeans/impl/store => common/org/apache/xmlbeans/impl/common}/XBLogFactory.java (97%)
|
|
rename src/{store/org/apache/xmlbeans/impl/store => common/org/apache/xmlbeans/impl/common}/XBLogger.java (97%)
|
|
|
|
diff --git a/src/common/org/apache/xmlbeans/impl/common/DocumentHelper.java b/src/common/org/apache/xmlbeans/impl/common/DocumentHelper.java
|
|
new file mode 100644
|
|
index 00000000..8c487644
|
|
--- /dev/null
|
|
+++ b/src/common/org/apache/xmlbeans/impl/common/DocumentHelper.java
|
|
@@ -0,0 +1,165 @@
|
|
+/* Copyright 2004-2018 The Apache Software Foundation
|
|
+ *
|
|
+ * Licensed 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.xmlbeans.impl.common;
|
|
+
|
|
+import java.io.IOException;
|
|
+import java.io.InputStream;
|
|
+import java.lang.reflect.Method;
|
|
+
|
|
+import javax.xml.XMLConstants;
|
|
+import javax.xml.parsers.DocumentBuilder;
|
|
+import javax.xml.parsers.DocumentBuilderFactory;
|
|
+import javax.xml.parsers.ParserConfigurationException;
|
|
+import javax.xml.stream.events.Namespace;
|
|
+
|
|
+import org.w3c.dom.Document;
|
|
+import org.w3c.dom.Element;
|
|
+import org.xml.sax.ErrorHandler;
|
|
+import org.xml.sax.InputSource;
|
|
+import org.xml.sax.SAXException;
|
|
+import org.xml.sax.SAXParseException;
|
|
+
|
|
+public final class DocumentHelper {
|
|
+ private static XBLogger logger = XBLogFactory.getLogger(DocumentHelper.class);
|
|
+
|
|
+ private DocumentHelper() {}
|
|
+
|
|
+ private static class DocHelperErrorHandler implements ErrorHandler {
|
|
+
|
|
+ public void warning(SAXParseException exception) throws SAXException {
|
|
+ printError(XBLogger.WARN, exception);
|
|
+ }
|
|
+
|
|
+ public void error(SAXParseException exception) throws SAXException {
|
|
+ printError(XBLogger.ERROR, exception);
|
|
+ }
|
|
+
|
|
+ public void fatalError(SAXParseException exception) throws SAXException {
|
|
+ printError(XBLogger.FATAL, exception);
|
|
+ throw exception;
|
|
+ }
|
|
+
|
|
+ /** Prints the error message. */
|
|
+ private void printError(int type, SAXParseException ex) {
|
|
+ StringBuilder sb = new StringBuilder();
|
|
+
|
|
+ String systemId = ex.getSystemId();
|
|
+ if (systemId != null) {
|
|
+ int index = systemId.lastIndexOf('/');
|
|
+ if (index != -1)
|
|
+ systemId = systemId.substring(index + 1);
|
|
+ sb.append(systemId);
|
|
+ }
|
|
+ sb.append(':');
|
|
+ sb.append(ex.getLineNumber());
|
|
+ sb.append(':');
|
|
+ sb.append(ex.getColumnNumber());
|
|
+ sb.append(": ");
|
|
+ sb.append(ex.getMessage());
|
|
+
|
|
+ logger.log(type, sb.toString(), ex);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Creates a new document builder, with sensible defaults
|
|
+ *
|
|
+ * @throws IllegalStateException If creating the DocumentBuilder fails, e.g.
|
|
+ * due to {@link ParserConfigurationException}.
|
|
+ */
|
|
+ public static synchronized DocumentBuilder newDocumentBuilder() {
|
|
+ try {
|
|
+ DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
|
|
+ documentBuilder.setEntityResolver(SAXHelper.IGNORING_ENTITY_RESOLVER);
|
|
+ documentBuilder.setErrorHandler(new DocHelperErrorHandler());
|
|
+ return documentBuilder;
|
|
+ } catch (ParserConfigurationException e) {
|
|
+ throw new IllegalStateException("cannot create a DocumentBuilder", e);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ private static final DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
|
|
+ static {
|
|
+ documentBuilderFactory.setNamespaceAware(true);
|
|
+ documentBuilderFactory.setValidating(false);
|
|
+ trySetSAXFeature(documentBuilderFactory, XMLConstants.FEATURE_SECURE_PROCESSING, true);
|
|
+ trySetXercesSecurityManager(documentBuilderFactory);
|
|
+ }
|
|
+
|
|
+ private static void trySetSAXFeature(DocumentBuilderFactory dbf, String feature, boolean enabled) {
|
|
+ try {
|
|
+ dbf.setFeature(feature, enabled);
|
|
+ } catch (Exception e) {
|
|
+ logger.log(XBLogger.WARN, "SAX Feature unsupported", feature, e);
|
|
+ } catch (AbstractMethodError ame) {
|
|
+ logger.log(XBLogger.WARN, "Cannot set SAX feature because outdated XML parser in classpath", feature, ame);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ private static void trySetXercesSecurityManager(DocumentBuilderFactory dbf) {
|
|
+ // Try built-in JVM one first, standalone if not
|
|
+ for (String securityManagerClassName : new String[]{
|
|
+ //"com.sun.org.apache.xerces.internal.util.SecurityManager",
|
|
+ "org.apache.xerces.util.SecurityManager"
|
|
+ }) {
|
|
+ try {
|
|
+ Object mgr = Class.forName(securityManagerClassName).newInstance();
|
|
+ Method setLimit = mgr.getClass().getMethod("setEntityExpansionLimit", Integer.TYPE);
|
|
+ setLimit.invoke(mgr, 4096);
|
|
+ dbf.setAttribute("http://apache.org/xml/properties/security-manager", mgr);
|
|
+ // Stop once one can be setup without error
|
|
+ return;
|
|
+ } catch (ClassNotFoundException e) {
|
|
+ // continue without log, this is expected in some setups
|
|
+ } catch (Throwable e) { // NOSONAR - also catch things like NoClassDefError here
|
|
+ logger.log(XBLogger.WARN, "SAX Security Manager could not be setup", e);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ // separate old version of Xerces not found => use the builtin way of setting the property
|
|
+ dbf.setAttribute("http://www.oracle.com/xml/jaxp/properties/entityExpansionLimit", 4096);
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Parses the given stream via the default (sensible)
|
|
+ * DocumentBuilder
|
|
+ * @param inp Stream to read the XML data from
|
|
+ * @return the parsed Document
|
|
+ */
|
|
+ public static Document readDocument(InputStream inp) throws IOException, SAXException {
|
|
+ return newDocumentBuilder().parse(inp);
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Parses the given stream via the default (sensible)
|
|
+ * DocumentBuilder
|
|
+ * @param inp sax source to read the XML data from
|
|
+ * @return the parsed Document
|
|
+ */
|
|
+ public static Document readDocument(InputSource inp) throws IOException, SAXException {
|
|
+ return newDocumentBuilder().parse(inp);
|
|
+ }
|
|
+
|
|
+ // must only be used to create empty documents, do not use it for parsing!
|
|
+ private static final DocumentBuilder documentBuilderSingleton = newDocumentBuilder();
|
|
+
|
|
+ /**
|
|
+ * Creates a new DOM Document
|
|
+ */
|
|
+ public static synchronized Document createDocument() {
|
|
+ return documentBuilderSingleton.newDocument();
|
|
+ }
|
|
+}
|
|
diff --git a/src/common/org/apache/xmlbeans/impl/common/LoadSaveUtils.java b/src/common/org/apache/xmlbeans/impl/common/LoadSaveUtils.java
|
|
index 74b52743..a80deff9 100644
|
|
--- a/src/common/org/apache/xmlbeans/impl/common/LoadSaveUtils.java
|
|
+++ b/src/common/org/apache/xmlbeans/impl/common/LoadSaveUtils.java
|
|
@@ -22,7 +22,6 @@ package org.apache.xmlbeans.impl.common;
|
|
import org.w3c.dom.Document;
|
|
import org.xml.sax.SAXException;
|
|
|
|
-import javax.xml.parsers.SAXParserFactory;
|
|
import javax.xml.parsers.SAXParser;
|
|
import javax.xml.parsers.ParserConfigurationException;
|
|
import javax.xml.stream.XMLStreamWriter;
|
|
@@ -40,10 +39,7 @@ public class LoadSaveUtils
|
|
public static Document xmlText2GenericDom(InputStream is, Document emptyDoc)
|
|
throws SAXException, ParserConfigurationException, IOException
|
|
{
|
|
- SAXParserFactory factory = SAXParserFactory.newInstance();
|
|
- factory.setNamespaceAware(true);
|
|
-
|
|
- SAXParser parser = factory.newSAXParser();
|
|
+ SAXParser parser = SAXHelper.saxFactory.newSAXParser();
|
|
|
|
Sax2Dom handler = new Sax2Dom(emptyDoc);
|
|
|
|
diff --git a/src/store/org/apache/xmlbeans/impl/store/NullLogger.java b/src/common/org/apache/xmlbeans/impl/common/NullLogger.java
|
|
similarity index 95%
|
|
rename from src/store/org/apache/xmlbeans/impl/store/NullLogger.java
|
|
rename to src/common/org/apache/xmlbeans/impl/common/NullLogger.java
|
|
index aca8d1d5..6b5874a4 100644
|
|
--- a/src/store/org/apache/xmlbeans/impl/store/NullLogger.java
|
|
+++ b/src/common/org/apache/xmlbeans/impl/common/NullLogger.java
|
|
@@ -1,4 +1,4 @@
|
|
-/* Copyright 2017 The Apache Software Foundation
|
|
+/* Copyright 2017, 2018 The Apache Software Foundation
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
@@ -13,7 +13,7 @@
|
|
* limitations under the License.
|
|
*/
|
|
|
|
-package org.apache.xmlbeans.impl.store;
|
|
+package org.apache.xmlbeans.impl.common;
|
|
|
|
/**
|
|
* A logger class that strives to make it as easy as possible for
|
|
diff --git a/src/store/org/apache/xmlbeans/impl/store/SAXHelper.java b/src/common/org/apache/xmlbeans/impl/common/SAXHelper.java
|
|
similarity index 96%
|
|
rename from src/store/org/apache/xmlbeans/impl/store/SAXHelper.java
|
|
rename to src/common/org/apache/xmlbeans/impl/common/SAXHelper.java
|
|
index 67fb3a0e..71bed2dc 100644
|
|
--- a/src/store/org/apache/xmlbeans/impl/store/SAXHelper.java
|
|
+++ b/src/common/org/apache/xmlbeans/impl/common/SAXHelper.java
|
|
@@ -1,4 +1,4 @@
|
|
-/* Copyright 2017 The Apache Software Foundation
|
|
+/* Copyright 2017, 2018 The Apache Software Foundation
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
@@ -13,7 +13,7 @@
|
|
* limitations under the License.
|
|
*/
|
|
|
|
-package org.apache.xmlbeans.impl.store;
|
|
+package org.apache.xmlbeans.impl.common;
|
|
|
|
import java.io.IOException;
|
|
import java.io.StringReader;
|
|
@@ -57,7 +57,7 @@ public final class SAXHelper {
|
|
}
|
|
};
|
|
|
|
- private static final SAXParserFactory saxFactory;
|
|
+ static final SAXParserFactory saxFactory;
|
|
static {
|
|
saxFactory = SAXParserFactory.newInstance();
|
|
saxFactory.setValidating(false);
|
|
diff --git a/src/common/org/apache/xmlbeans/impl/common/Sax2Dom.java b/src/common/org/apache/xmlbeans/impl/common/Sax2Dom.java
|
|
index 67294bb8..989eafcb 100644
|
|
--- a/src/common/org/apache/xmlbeans/impl/common/Sax2Dom.java
|
|
+++ b/src/common/org/apache/xmlbeans/impl/common/Sax2Dom.java
|
|
@@ -28,7 +28,6 @@ import org.xml.sax.helpers.DefaultHandler;
|
|
import org.xml.sax.ext.LexicalHandler;
|
|
|
|
import javax.xml.parsers.ParserConfigurationException;
|
|
-import javax.xml.parsers.DocumentBuilderFactory;
|
|
import java.util.Stack;
|
|
import java.util.Vector;
|
|
|
|
@@ -49,9 +48,7 @@ public class Sax2Dom
|
|
|
|
public Sax2Dom() throws ParserConfigurationException
|
|
{
|
|
- final DocumentBuilderFactory factory =
|
|
- DocumentBuilderFactory.newInstance();
|
|
- _document = factory.newDocumentBuilder().newDocument();
|
|
+ _document = DocumentHelper.newDocumentBuilder().newDocument();
|
|
_root = _document;
|
|
}
|
|
|
|
@@ -68,9 +65,7 @@ public class Sax2Dom
|
|
}
|
|
else
|
|
{
|
|
- final DocumentBuilderFactory factory =
|
|
- DocumentBuilderFactory.newInstance();
|
|
- _document = factory.newDocumentBuilder().newDocument();
|
|
+ _document = DocumentHelper.newDocumentBuilder().newDocument();
|
|
_root = _document;
|
|
}
|
|
}
|
|
diff --git a/src/store/org/apache/xmlbeans/impl/store/XBLogFactory.java b/src/common/org/apache/xmlbeans/impl/common/XBLogFactory.java
|
|
similarity index 97%
|
|
rename from src/store/org/apache/xmlbeans/impl/store/XBLogFactory.java
|
|
rename to src/common/org/apache/xmlbeans/impl/common/XBLogFactory.java
|
|
index f31d4db7..0afac4d5 100644
|
|
--- a/src/store/org/apache/xmlbeans/impl/store/XBLogFactory.java
|
|
+++ b/src/common/org/apache/xmlbeans/impl/common/XBLogFactory.java
|
|
@@ -1,4 +1,4 @@
|
|
-/* Copyright 2017 The Apache Software Foundation
|
|
+/* Copyright 2017, 2018 The Apache Software Foundation
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
@@ -13,7 +13,7 @@
|
|
* limitations under the License.
|
|
*/
|
|
|
|
-package org.apache.xmlbeans.impl.store;
|
|
+package org.apache.xmlbeans.impl.common;
|
|
|
|
import java.util.HashMap;
|
|
import java.util.Map;
|
|
diff --git a/src/store/org/apache/xmlbeans/impl/store/XBLogger.java b/src/common/org/apache/xmlbeans/impl/common/XBLogger.java
|
|
similarity index 97%
|
|
rename from src/store/org/apache/xmlbeans/impl/store/XBLogger.java
|
|
rename to src/common/org/apache/xmlbeans/impl/common/XBLogger.java
|
|
index fa605112..b1394226 100644
|
|
--- a/src/store/org/apache/xmlbeans/impl/store/XBLogger.java
|
|
+++ b/src/common/org/apache/xmlbeans/impl/common/XBLogger.java
|
|
@@ -1,4 +1,4 @@
|
|
-/* Copyright 2017 The Apache Software Foundation
|
|
+/* Copyright 2017, 2018 The Apache Software Foundation
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
@@ -13,7 +13,7 @@
|
|
* limitations under the License.
|
|
*/
|
|
|
|
-package org.apache.xmlbeans.impl.store;
|
|
+package org.apache.xmlbeans.impl.common;
|
|
|
|
/**
|
|
* A logger interface that strives to make it as easy as possible for
|
|
diff --git a/src/store/org/apache/xmlbeans/impl/store/Locale.java b/src/store/org/apache/xmlbeans/impl/store/Locale.java
|
|
index 1f02a160..4a4d5927 100644
|
|
--- a/src/store/org/apache/xmlbeans/impl/store/Locale.java
|
|
+++ b/src/store/org/apache/xmlbeans/impl/store/Locale.java
|
|
@@ -1,4 +1,4 @@
|
|
-/* Copyright 2004 The Apache Software Foundation
|
|
+/* Copyright 2004-2018 The Apache Software Foundation
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
@@ -15,7 +15,6 @@
|
|
|
|
package org.apache.xmlbeans.impl.store;
|
|
|
|
-import org.apache.xmlbeans.XmlErrorCodes;
|
|
import org.xml.sax.Locator;
|
|
import org.xml.sax.Attributes;
|
|
import org.xml.sax.ContentHandler;
|
|
@@ -45,6 +44,7 @@ import java.io.Reader;
|
|
import java.io.StringReader;
|
|
import java.io.IOException;
|
|
|
|
+import javax.xml.namespace.QName;
|
|
import javax.xml.stream.XMLStreamReader;
|
|
import javax.xml.stream.XMLStreamException;
|
|
|
|
@@ -59,15 +59,7 @@ import org.apache.xmlbeans.xml.stream.XMLEvent;
|
|
import org.apache.xmlbeans.xml.stream.XMLInputStream;
|
|
import org.apache.xmlbeans.xml.stream.XMLName;
|
|
|
|
-import org.w3c.dom.DOMImplementation;
|
|
-import org.w3c.dom.Document;
|
|
-import org.w3c.dom.DocumentType;
|
|
-import org.w3c.dom.Node;
|
|
-import org.w3c.dom.NamedNodeMap;
|
|
-import org.w3c.dom.Element;
|
|
-
|
|
-import javax.xml.namespace.QName;
|
|
-
|
|
+import org.apache.xmlbeans.impl.common.SAXHelper;
|
|
import org.apache.xmlbeans.impl.common.XMLNameHelper;
|
|
import org.apache.xmlbeans.impl.common.QNameHelper;
|
|
import org.apache.xmlbeans.impl.common.XmlLocale;
|
|
@@ -89,10 +81,11 @@ import org.apache.xmlbeans.XmlBeans;
|
|
import org.apache.xmlbeans.XmlLineNumber;
|
|
import org.apache.xmlbeans.XmlCursor;
|
|
import org.apache.xmlbeans.XmlCursor.XmlBookmark;
|
|
-import org.apache.xmlbeans.XmlSaxHandler;
|
|
+import org.apache.xmlbeans.XmlErrorCodes;
|
|
import org.apache.xmlbeans.XmlException;
|
|
import org.apache.xmlbeans.XmlObject;
|
|
import org.apache.xmlbeans.XmlOptions;
|
|
+import org.apache.xmlbeans.XmlSaxHandler;
|
|
import org.apache.xmlbeans.SchemaType;
|
|
import org.apache.xmlbeans.SchemaTypeLoader;
|
|
import org.apache.xmlbeans.XmlTokenSource;
|
|
@@ -109,6 +102,13 @@ import org.apache.xmlbeans.impl.values.TypeStoreUserFactory;
|
|
import org.apache.xmlbeans.impl.piccolo.xml.Piccolo;
|
|
import org.apache.xmlbeans.impl.piccolo.io.FileFormatException;
|
|
|
|
+import org.w3c.dom.DOMImplementation;
|
|
+import org.w3c.dom.Document;
|
|
+import org.w3c.dom.DocumentType;
|
|
+import org.w3c.dom.Node;
|
|
+import org.w3c.dom.NamedNodeMap;
|
|
+import org.w3c.dom.Element;
|
|
+
|
|
public final class Locale
|
|
implements DOMImplementation, SaajCallback, XmlLocale
|
|
{
|
|
--
|
|
2.23.0
|
|
|