|
@@ -18,12 +18,19 @@
|
|
|
|
|
|
package org.apache.hadoop.util;
|
|
package org.apache.hadoop.util;
|
|
|
|
|
|
|
|
+import javax.xml.XMLConstants;
|
|
|
|
+import javax.xml.parsers.DocumentBuilderFactory;
|
|
|
|
+import javax.xml.parsers.ParserConfigurationException;
|
|
|
|
+import javax.xml.parsers.SAXParserFactory;
|
|
import javax.xml.transform.*;
|
|
import javax.xml.transform.*;
|
|
|
|
+import javax.xml.transform.sax.SAXTransformerFactory;
|
|
import javax.xml.transform.stream.*;
|
|
import javax.xml.transform.stream.*;
|
|
|
|
|
|
import org.apache.hadoop.classification.InterfaceAudience;
|
|
import org.apache.hadoop.classification.InterfaceAudience;
|
|
import org.apache.hadoop.classification.InterfaceStability;
|
|
import org.apache.hadoop.classification.InterfaceStability;
|
|
|
|
|
|
|
|
+import org.xml.sax.SAXException;
|
|
|
|
+
|
|
import java.io.*;
|
|
import java.io.*;
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -33,6 +40,19 @@ import java.io.*;
|
|
@InterfaceAudience.Private
|
|
@InterfaceAudience.Private
|
|
@InterfaceStability.Unstable
|
|
@InterfaceStability.Unstable
|
|
public class XMLUtils {
|
|
public class XMLUtils {
|
|
|
|
+
|
|
|
|
+ private static final String DISALLOW_DOCTYPE_DECL =
|
|
|
|
+ "http://apache.org/xml/features/disallow-doctype-decl";
|
|
|
|
+ private static final String LOAD_EXTERNAL_DECL =
|
|
|
|
+ "http://apache.org/xml/features/nonvalidating/load-external-dtd";
|
|
|
|
+ private static final String EXTERNAL_GENERAL_ENTITIES =
|
|
|
|
+ "http://xml.org/sax/features/external-general-entities";
|
|
|
|
+ private static final String EXTERNAL_PARAMETER_ENTITIES =
|
|
|
|
+ "http://xml.org/sax/features/external-parameter-entities";
|
|
|
|
+ private static final String CREATE_ENTITY_REF_NODES =
|
|
|
|
+ "http://apache.org/xml/features/dom/create-entity-ref-nodes";
|
|
|
|
+
|
|
|
|
+
|
|
/**
|
|
/**
|
|
* Transform input xml given a stylesheet.
|
|
* Transform input xml given a stylesheet.
|
|
*
|
|
*
|
|
@@ -49,7 +69,7 @@ public class XMLUtils {
|
|
)
|
|
)
|
|
throws TransformerConfigurationException, TransformerException {
|
|
throws TransformerConfigurationException, TransformerException {
|
|
// Instantiate a TransformerFactory
|
|
// Instantiate a TransformerFactory
|
|
- TransformerFactory tFactory = TransformerFactory.newInstance();
|
|
|
|
|
|
+ TransformerFactory tFactory = newSecureTransformerFactory();
|
|
|
|
|
|
// Use the TransformerFactory to process the
|
|
// Use the TransformerFactory to process the
|
|
// stylesheet and generate a Transformer
|
|
// stylesheet and generate a Transformer
|
|
@@ -61,4 +81,82 @@ public class XMLUtils {
|
|
// and send the output to a Result object.
|
|
// and send the output to a Result object.
|
|
transformer.transform(new StreamSource(xml), new StreamResult(out));
|
|
transformer.transform(new StreamSource(xml), new StreamResult(out));
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * This method should be used if you need a {@link DocumentBuilderFactory}. Use this method
|
|
|
|
+ * instead of {@link DocumentBuilderFactory#newInstance()}. The factory that is returned has
|
|
|
|
+ * secure configuration enabled.
|
|
|
|
+ *
|
|
|
|
+ * @return a {@link DocumentBuilderFactory} with secure configuration enabled
|
|
|
|
+ * @throws ParserConfigurationException if the {@code JAXP} parser does not support the
|
|
|
|
+ * secure configuration
|
|
|
|
+ */
|
|
|
|
+ public static DocumentBuilderFactory newSecureDocumentBuilderFactory()
|
|
|
|
+ throws ParserConfigurationException {
|
|
|
|
+ DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
|
|
|
|
+ dbf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
|
|
|
|
+ dbf.setFeature(DISALLOW_DOCTYPE_DECL, true);
|
|
|
|
+ dbf.setFeature(LOAD_EXTERNAL_DECL, false);
|
|
|
|
+ dbf.setFeature(EXTERNAL_GENERAL_ENTITIES, false);
|
|
|
|
+ dbf.setFeature(EXTERNAL_PARAMETER_ENTITIES, false);
|
|
|
|
+ dbf.setFeature(CREATE_ENTITY_REF_NODES, false);
|
|
|
|
+ return dbf;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * This method should be used if you need a {@link SAXParserFactory}. Use this method
|
|
|
|
+ * instead of {@link SAXParserFactory#newInstance()}. The factory that is returned has
|
|
|
|
+ * secure configuration enabled.
|
|
|
|
+ *
|
|
|
|
+ * @return a {@link SAXParserFactory} with secure configuration enabled
|
|
|
|
+ * @throws ParserConfigurationException if the {@code JAXP} parser does not support the
|
|
|
|
+ * secure configuration
|
|
|
|
+ * @throws SAXException if there are another issues when creating the factory
|
|
|
|
+ */
|
|
|
|
+ public static SAXParserFactory newSecureSAXParserFactory()
|
|
|
|
+ throws SAXException, ParserConfigurationException {
|
|
|
|
+ SAXParserFactory spf = SAXParserFactory.newInstance();
|
|
|
|
+ spf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
|
|
|
|
+ spf.setFeature(DISALLOW_DOCTYPE_DECL, true);
|
|
|
|
+ spf.setFeature(LOAD_EXTERNAL_DECL, false);
|
|
|
|
+ spf.setFeature(EXTERNAL_GENERAL_ENTITIES, false);
|
|
|
|
+ spf.setFeature(EXTERNAL_PARAMETER_ENTITIES, false);
|
|
|
|
+ return spf;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * This method should be used if you need a {@link TransformerFactory}. Use this method
|
|
|
|
+ * instead of {@link TransformerFactory#newInstance()}. The factory that is returned has
|
|
|
|
+ * secure configuration enabled.
|
|
|
|
+ *
|
|
|
|
+ * @return a {@link TransformerFactory} with secure configuration enabled
|
|
|
|
+ * @throws TransformerConfigurationException if the {@code JAXP} transformer does not
|
|
|
|
+ * support the secure configuration
|
|
|
|
+ */
|
|
|
|
+ public static TransformerFactory newSecureTransformerFactory()
|
|
|
|
+ throws TransformerConfigurationException {
|
|
|
|
+ TransformerFactory trfactory = TransformerFactory.newInstance();
|
|
|
|
+ trfactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
|
|
|
|
+ trfactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "");
|
|
|
|
+ trfactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, "");
|
|
|
|
+ return trfactory;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * This method should be used if you need a {@link SAXTransformerFactory}. Use this method
|
|
|
|
+ * instead of {@link SAXTransformerFactory#newInstance()}. The factory that is returned has
|
|
|
|
+ * secure configuration enabled.
|
|
|
|
+ *
|
|
|
|
+ * @return a {@link SAXTransformerFactory} with secure configuration enabled
|
|
|
|
+ * @throws TransformerConfigurationException if the {@code JAXP} transformer does not
|
|
|
|
+ * support the secure configuration
|
|
|
|
+ */
|
|
|
|
+ public static SAXTransformerFactory newSecureSAXTransformerFactory()
|
|
|
|
+ throws TransformerConfigurationException {
|
|
|
|
+ SAXTransformerFactory trfactory = (SAXTransformerFactory) SAXTransformerFactory.newInstance();
|
|
|
|
+ trfactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
|
|
|
|
+ trfactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "");
|
|
|
|
+ trfactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, "");
|
|
|
|
+ return trfactory;
|
|
|
|
+ }
|
|
}
|
|
}
|