< prev index next >

src/share/jaxws_classes/com/sun/xml/internal/ws/util/xml/XmlUtil.java

Print this page
rev 1143 : 8182054: Improve wsdl support
Summary: Also reviewed by Roman Grigoriadi <roman.grigoriadi@oracle.com>
Reviewed-by: joehw, lancea

@@ -1,7 +1,7 @@
 /*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 only, as
  * published by the Free Software Foundation.  Oracle designates this

@@ -38,45 +38,77 @@
 import org.w3c.dom.NodeList;
 import org.w3c.dom.Text;
 import org.xml.sax.EntityResolver;
 import org.xml.sax.ErrorHandler;
 import org.xml.sax.SAXException;
+import org.xml.sax.SAXNotRecognizedException;
+import org.xml.sax.SAXNotSupportedException;
 import org.xml.sax.SAXParseException;
 import org.xml.sax.XMLReader;
 import org.xml.sax.InputSource;
 
+import javax.xml.XMLConstants;
 import javax.xml.namespace.QName;
+import javax.xml.parsers.DocumentBuilderFactory;
 import javax.xml.parsers.ParserConfigurationException;
 import javax.xml.parsers.SAXParserFactory;
+import javax.xml.stream.XMLInputFactory;
 import javax.xml.transform.Result;
 import javax.xml.transform.Source;
 import javax.xml.transform.Transformer;
 import javax.xml.transform.TransformerConfigurationException;
 import javax.xml.transform.TransformerException;
 import javax.xml.transform.TransformerFactory;
 import javax.xml.transform.sax.SAXTransformerFactory;
 import javax.xml.transform.sax.TransformerHandler;
 import javax.xml.transform.stream.StreamSource;
 import javax.xml.ws.WebServiceException;
+import javax.xml.xpath.XPathFactory;
+import javax.xml.xpath.XPathFactoryConfigurationException;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStreamWriter;
 import java.io.Writer;
 import java.net.URL;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
 import java.util.ArrayList;
 import java.util.Enumeration;
 import java.util.Iterator;
 import java.util.List;
 import java.util.StringTokenizer;
+import java.util.logging.Level;
+import java.util.logging.Logger;
 
 /**
  * @author WS Development Team
  */
 public class XmlUtil {
     private final static String LEXICAL_HANDLER_PROPERTY =
         "http://xml.org/sax/properties/lexical-handler";
 
+    private static final String DISALLOW_DOCTYPE_DECL = "http://apache.org/xml/features/disallow-doctype-decl";
+
+    private static final String EXTERNAL_GE = "http://xml.org/sax/features/external-general-entities";
+
+    private static final String EXTERNAL_PE = "http://xml.org/sax/features/external-parameter-entities";
+
+    private static final String LOAD_EXTERNAL_DTD = "http://apache.org/xml/features/nonvalidating/load-external-dtd";
+
+    private static final Logger LOGGER = Logger.getLogger(XmlUtil.class.getName());
+
+    private static final String DISABLE_XML_SECURITY = "com.sun.xml.internal.ws.disableXmlSecurity";
+
+    private static boolean XML_SECURITY_DISABLED = AccessController.doPrivileged(
+            new PrivilegedAction<Boolean>() {
+                @Override
+                public Boolean run() {
+                    return Boolean.getBoolean(DISABLE_XML_SECURITY);
+                }
+            }
+    );
+
     public static String getPrefix(String s) {
         int i = s.indexOf(':');
         if (i == -1)
             return null;
         return s.substring(0, i);

@@ -161,11 +193,11 @@
         }
         return result;
     }
 
     public static String getTextForNode(Node node) {
-        StringBuffer sb = new StringBuffer();
+        StringBuilder sb = new StringBuilder();
 
         NodeList children = node.getChildNodes();
         if (children.getLength() == 0)
             return null;
 

@@ -332,17 +364,110 @@
 
     /**
      * {@link ErrorHandler} that always treat the error as fatal.
      */
     public static final ErrorHandler DRACONIAN_ERROR_HANDLER = new ErrorHandler() {
+        @Override
         public void warning(SAXParseException exception) {
         }
 
+        @Override
         public void error(SAXParseException exception) throws SAXException {
             throw exception;
         }
 
+        @Override
         public void fatalError(SAXParseException exception) throws SAXException {
             throw exception;
         }
     };
+
+    public static DocumentBuilderFactory newDocumentBuilderFactory() {
+        return newDocumentBuilderFactory(false);
+    }
+
+    public static DocumentBuilderFactory newDocumentBuilderFactory(boolean disableSecurity) {
+        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+        String featureToSet = XMLConstants.FEATURE_SECURE_PROCESSING;
+        try {
+            boolean securityOn = !isXMLSecurityDisabled(disableSecurity);
+            factory.setFeature(featureToSet, securityOn);
+            factory.setNamespaceAware(true);
+            if (securityOn) {
+                factory.setExpandEntityReferences(false);
+                featureToSet = DISALLOW_DOCTYPE_DECL;
+                factory.setFeature(featureToSet, true);
+                featureToSet = EXTERNAL_GE;
+                factory.setFeature(featureToSet, false);
+                featureToSet = EXTERNAL_PE;
+                factory.setFeature(featureToSet, false);
+                featureToSet = LOAD_EXTERNAL_DTD;
+                factory.setFeature(featureToSet, false);
+            }
+        } catch (ParserConfigurationException e) {
+            LOGGER.log(Level.WARNING, "Factory [{0}] doesn't support "+featureToSet+" feature!", new Object[] {factory.getClass().getName()} );
+        }
+        return factory;
+    }
+
+    public static TransformerFactory newTransformerFactory(boolean secureXmlProcessingEnabled) {
+        TransformerFactory factory = TransformerFactory.newInstance();
+        try {
+            factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, isXMLSecurityDisabled(secureXmlProcessingEnabled));
+        } catch (TransformerConfigurationException e) {
+            LOGGER.log(Level.WARNING, "Factory [{0}] doesn't support secure xml processing!", new Object[]{factory.getClass().getName()});
+        }
+        return factory;
+    }
+
+    public static TransformerFactory newTransformerFactory() {
+        return newTransformerFactory(true);
+    }
+
+    public static SAXParserFactory newSAXParserFactory(boolean disableSecurity) {
+        SAXParserFactory factory = SAXParserFactory.newInstance();
+        String featureToSet = XMLConstants.FEATURE_SECURE_PROCESSING;
+        try {
+            boolean securityOn = !isXMLSecurityDisabled(disableSecurity);
+            factory.setFeature(featureToSet, securityOn);
+            factory.setNamespaceAware(true);
+            if (securityOn) {
+                featureToSet = DISALLOW_DOCTYPE_DECL;
+                factory.setFeature(featureToSet, true);
+                featureToSet = EXTERNAL_GE;
+                factory.setFeature(featureToSet, false);
+                featureToSet = EXTERNAL_PE;
+                factory.setFeature(featureToSet, false);
+                featureToSet = LOAD_EXTERNAL_DTD;
+                factory.setFeature(featureToSet, false);
+            }
+        } catch (ParserConfigurationException | SAXNotRecognizedException | SAXNotSupportedException e) {
+            LOGGER.log(Level.WARNING, "Factory [{0}] doesn't support "+featureToSet+" feature!", new Object[]{factory.getClass().getName()});
+        }
+        return factory;
+    }
+
+    public static XPathFactory newXPathFactory(boolean secureXmlProcessingEnabled) {
+        XPathFactory factory = XPathFactory.newInstance();
+        try {
+            factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, isXMLSecurityDisabled(secureXmlProcessingEnabled));
+        } catch (XPathFactoryConfigurationException e) {
+            LOGGER.log(Level.WARNING, "Factory [{0}] doesn't support secure xml processing!", new Object[] { factory.getClass().getName() } );
+        }
+        return factory;
+    }
+
+    public static XMLInputFactory newXMLInputFactory(boolean secureXmlProcessingEnabled)  {
+        XMLInputFactory factory = XMLInputFactory.newInstance();
+        if (isXMLSecurityDisabled(secureXmlProcessingEnabled)) {
+            // TODO-Miran: are those apppropriate defaults?
+            factory.setProperty(XMLInputFactory.SUPPORT_DTD, false);
+            factory.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false);
+        }
+        return factory;
+    }
+
+    private static boolean isXMLSecurityDisabled(boolean runtimeDisabled) {
+        return XML_SECURITY_DISABLED || runtimeDisabled;
+    }
+
 }
< prev index next >