|
@@ -34,6 +34,7 @@ import org.slf4j.LoggerFactory;
|
|
import org.xml.sax.SAXException;
|
|
import org.xml.sax.SAXException;
|
|
|
|
|
|
import java.io.*;
|
|
import java.io.*;
|
|
|
|
+import java.util.concurrent.atomic.AtomicBoolean;
|
|
|
|
|
|
/**
|
|
/**
|
|
* General xml utilities.
|
|
* General xml utilities.
|
|
@@ -59,6 +60,11 @@ public class XMLUtils {
|
|
public static final String VALIDATION =
|
|
public static final String VALIDATION =
|
|
"http://xml.org/sax/features/validation";
|
|
"http://xml.org/sax/features/validation";
|
|
|
|
|
|
|
|
+ private static final AtomicBoolean CAN_SET_TRANSFORMER_ACCESS_EXTERNAL_DTD =
|
|
|
|
+ new AtomicBoolean(true);
|
|
|
|
+ private static final AtomicBoolean CAN_SET_TRANSFORMER_ACCESS_EXTERNAL_STYLESHEET =
|
|
|
|
+ new AtomicBoolean(true);
|
|
|
|
+
|
|
/**
|
|
/**
|
|
* Transform input xml given a stylesheet.
|
|
* Transform input xml given a stylesheet.
|
|
*
|
|
*
|
|
@@ -143,8 +149,7 @@ public class XMLUtils {
|
|
throws TransformerConfigurationException {
|
|
throws TransformerConfigurationException {
|
|
TransformerFactory trfactory = TransformerFactory.newInstance();
|
|
TransformerFactory trfactory = TransformerFactory.newInstance();
|
|
trfactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
|
|
trfactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
|
|
- bestEffortSetAttribute(trfactory, XMLConstants.ACCESS_EXTERNAL_DTD, "");
|
|
|
|
- bestEffortSetAttribute(trfactory, XMLConstants.ACCESS_EXTERNAL_STYLESHEET, "");
|
|
|
|
|
|
+ setOptionalSecureTransformerAttributes(trfactory);
|
|
return trfactory;
|
|
return trfactory;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -161,29 +166,45 @@ public class XMLUtils {
|
|
throws TransformerConfigurationException {
|
|
throws TransformerConfigurationException {
|
|
SAXTransformerFactory trfactory = (SAXTransformerFactory) SAXTransformerFactory.newInstance();
|
|
SAXTransformerFactory trfactory = (SAXTransformerFactory) SAXTransformerFactory.newInstance();
|
|
trfactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
|
|
trfactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
|
|
- bestEffortSetAttribute(trfactory, XMLConstants.ACCESS_EXTERNAL_DTD, "");
|
|
|
|
- bestEffortSetAttribute(trfactory, XMLConstants.ACCESS_EXTERNAL_STYLESHEET, "");
|
|
|
|
|
|
+ setOptionalSecureTransformerAttributes(trfactory);
|
|
return trfactory;
|
|
return trfactory;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
+ * These attributes are recommended for maximum security but some JAXP transformers do
|
|
|
|
+ * not support them. If at any stage, we fail to set these attributes, then we won't try again
|
|
|
|
+ * for subsequent transformers.
|
|
|
|
+ *
|
|
|
|
+ * @param transformerFactory to update
|
|
|
|
+ */
|
|
|
|
+ private static void setOptionalSecureTransformerAttributes(
|
|
|
|
+ TransformerFactory transformerFactory) {
|
|
|
|
+ bestEffortSetAttribute(transformerFactory, CAN_SET_TRANSFORMER_ACCESS_EXTERNAL_DTD,
|
|
|
|
+ XMLConstants.ACCESS_EXTERNAL_DTD, "");
|
|
|
|
+ bestEffortSetAttribute(transformerFactory, CAN_SET_TRANSFORMER_ACCESS_EXTERNAL_STYLESHEET,
|
|
|
|
+ XMLConstants.ACCESS_EXTERNAL_STYLESHEET, "");
|
|
|
|
+ }
|
|
|
|
+
|
|
/**
|
|
/**
|
|
* Set an attribute value on a {@link TransformerFactory}. If the TransformerFactory
|
|
* Set an attribute value on a {@link TransformerFactory}. If the TransformerFactory
|
|
* does not support the attribute, the method just returns <code>false</code> and
|
|
* does not support the attribute, the method just returns <code>false</code> and
|
|
* logs the issue at debug level.
|
|
* logs the issue at debug level.
|
|
*
|
|
*
|
|
* @param transformerFactory to update
|
|
* @param transformerFactory to update
|
|
|
|
+ * @param flag that indicates whether to do the update and the flag can be set to
|
|
|
|
+ * <code>false</code> if an update fails
|
|
* @param name of the attribute to set
|
|
* @param name of the attribute to set
|
|
* @param value to set on the attribute
|
|
* @param value to set on the attribute
|
|
- * @return whether the attribute was successfully set
|
|
|
|
*/
|
|
*/
|
|
- static boolean bestEffortSetAttribute(TransformerFactory transformerFactory,
|
|
|
|
- String name, Object value) {
|
|
|
|
- try {
|
|
|
|
- transformerFactory.setAttribute(name, value);
|
|
|
|
- return true;
|
|
|
|
- } catch (Throwable t) {
|
|
|
|
- LOG.debug("Issue setting TransformerFactory attribute {}: {}", name, t.toString());
|
|
|
|
|
|
+ static void bestEffortSetAttribute(TransformerFactory transformerFactory, AtomicBoolean flag,
|
|
|
|
+ String name, Object value) {
|
|
|
|
+ if (flag.get()) {
|
|
|
|
+ try {
|
|
|
|
+ transformerFactory.setAttribute(name, value);
|
|
|
|
+ } catch (Throwable t) {
|
|
|
|
+ flag.set(false);
|
|
|
|
+ LOG.debug("Issue setting TransformerFactory attribute {}: {}", name, t.toString());
|
|
|
|
+ }
|
|
}
|
|
}
|
|
- return false;
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|