diff --git a/impl/src/main/java/com/sun/faces/config/manager/Documents.java b/impl/src/main/java/com/sun/faces/config/manager/Documents.java index e90fd44df6..218445a90e 100644 --- a/impl/src/main/java/com/sun/faces/config/manager/Documents.java +++ b/impl/src/main/java/com/sun/faces/config/manager/Documents.java @@ -18,6 +18,7 @@ import static com.sun.faces.RIConstants.DOCUMENT_NAMESPACE; import static com.sun.faces.RIConstants.DOCUMENT_VERSION; +import static com.sun.faces.util.Util.createLocalDocumentBuilderFactory; import static com.sun.faces.util.Util.isEmpty; import static java.util.Arrays.asList; import static java.util.logging.Level.INFO; @@ -231,7 +232,7 @@ public static DocumentInfo[] sortDocuments(DocumentInfo[] facesDocuments, FacesC } private static DOMImplementation createDOMImplementation() throws ParserConfigurationException { - DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); + DocumentBuilderFactory documentBuilderFactory = createLocalDocumentBuilderFactory(); documentBuilderFactory.setNamespaceAware(true); return documentBuilderFactory.newDocumentBuilder().getDOMImplementation(); diff --git a/impl/src/main/java/com/sun/faces/config/processor/FacesFlowDefinitionConfigProcessor.java b/impl/src/main/java/com/sun/faces/config/processor/FacesFlowDefinitionConfigProcessor.java index 77da79922c..3ac07b6f51 100644 --- a/impl/src/main/java/com/sun/faces/config/processor/FacesFlowDefinitionConfigProcessor.java +++ b/impl/src/main/java/com/sun/faces/config/processor/FacesFlowDefinitionConfigProcessor.java @@ -16,6 +16,7 @@ package com.sun.faces.config.processor; +import static com.sun.faces.util.Util.createLocalDocumentBuilderFactory; import static com.sun.faces.util.Util.notNull; import java.net.MalformedURLException; @@ -127,7 +128,7 @@ public static Document synthesizeEmptyFlowDefinition(URI uri) throws ParserConfi } String flowName = segments[segments.length - 2]; - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + DocumentBuilderFactory dbf = createLocalDocumentBuilderFactory(); dbf.setNamespaceAware(true); DocumentBuilder builder = dbf.newDocumentBuilder(); DOMImplementation domImpl = builder.getDOMImplementation(); diff --git a/impl/src/main/java/com/sun/faces/util/Util.java b/impl/src/main/java/com/sun/faces/util/Util.java index 14c62e2db7..7ae95e534d 100644 --- a/impl/src/main/java/com/sun/faces/util/Util.java +++ b/impl/src/main/java/com/sun/faces/util/Util.java @@ -62,6 +62,7 @@ import javax.naming.InitialContext; import javax.naming.NamingException; +import javax.xml.XMLConstants; import javax.xml.namespace.NamespaceContext; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; @@ -269,12 +270,27 @@ public static boolean isUnitTestModeEnabled() { return unitTestModeEnabled; } + public static interface ThrowingBiConsumer { + void accept(T t, U u) throws Exception; + } + + private static void setPossiblyUnsupportedFeature(ThrowingBiConsumer setter, F feature, Boolean flag) { + try { + setter.accept(feature, flag); + } catch (Exception e) { + throw new IllegalStateException("The feature '" + feature + "' is not supported by your XML processor.", e); + } + } + public static TransformerFactory createTransformerFactory() { ClassLoader cl = Thread.currentThread().getContextClassLoader(); TransformerFactory factory; try { Thread.currentThread().setContextClassLoader(Util.class.getClassLoader()); factory = TransformerFactory.newInstance(); + factory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, ""); + factory.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, ""); + setPossiblyUnsupportedFeature(factory::setFeature, XMLConstants.FEATURE_SECURE_PROCESSING, true); } finally { Thread.currentThread().setContextClassLoader(cl); } @@ -298,13 +314,25 @@ public static DocumentBuilderFactory createDocumentBuilderFactory() { DocumentBuilderFactory factory; try { Thread.currentThread().setContextClassLoader(Util.class.getClassLoader()); - factory = DocumentBuilderFactory.newInstance(); + factory = createLocalDocumentBuilderFactory(); } finally { Thread.currentThread().setContextClassLoader(cl); } return factory; } + public static DocumentBuilderFactory createLocalDocumentBuilderFactory() { + DocumentBuilderFactory factory; + factory = DocumentBuilderFactory.newInstance(); + setPossiblyUnsupportedFeature(factory::setFeature, "http://xml.org/sax/features/external-parameter-entities", false); + setPossiblyUnsupportedFeature(factory::setFeature, "http://apache.org/xml/features/nonvalidating/load-external-dtd", false); + setPossiblyUnsupportedFeature(factory::setFeature, "http://xml.org/sax/features/external-general-entities", false); + factory.setXIncludeAware(false); + factory.setExpandEntityReferences(false); + setPossiblyUnsupportedFeature(factory::setFeature, XMLConstants.FEATURE_SECURE_PROCESSING, true); + return factory; + } + public static SchemaFactory createSchemaFactory(String uri) { ClassLoader cl = Thread.currentThread().getContextClassLoader(); SchemaFactory factory; diff --git a/impl/src/test/java/com/sun/faces/config/processor/FacesConfigNamespaceContextTest.java b/impl/src/test/java/com/sun/faces/config/processor/FacesConfigNamespaceContextTest.java index d4d1150b59..cb59988b72 100644 --- a/impl/src/test/java/com/sun/faces/config/processor/FacesConfigNamespaceContextTest.java +++ b/impl/src/test/java/com/sun/faces/config/processor/FacesConfigNamespaceContextTest.java @@ -16,6 +16,7 @@ package com.sun.faces.config.processor; +import static com.sun.faces.util.Util.createLocalDocumentBuilderFactory; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; @@ -79,7 +80,7 @@ public void testJakartaEENSWithParameter() throws ParserConfigurationException, private Document createFacesConfig(String flowName, String namespace, String version) throws ParserConfigurationException { - DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); + DocumentBuilderFactory documentBuilderFactory = createLocalDocumentBuilderFactory(); documentBuilderFactory.setNamespaceAware(true); DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder(); Document docFlowConfig = documentBuilder.newDocument(); diff --git a/impl/src/test/java/jakarta/faces/FacesConfigOrderingTestCase.java b/impl/src/test/java/jakarta/faces/FacesConfigOrderingTestCase.java index c5c7187bfb..c072c4fd98 100644 --- a/impl/src/test/java/jakarta/faces/FacesConfigOrderingTestCase.java +++ b/impl/src/test/java/jakarta/faces/FacesConfigOrderingTestCase.java @@ -16,6 +16,8 @@ package jakarta.faces; +import static com.sun.faces.util.Util.createLocalDocumentBuilderFactory; + import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Arrays; @@ -25,10 +27,6 @@ import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; -import junit.framework.Test; -import junit.framework.TestCase; -import junit.framework.TestSuite; - import org.w3c.dom.Document; import org.w3c.dom.Element; @@ -36,6 +34,9 @@ import com.sun.faces.config.manager.documents.DocumentOrderingWrapper; import jakarta.faces.context.FacesContext; +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; public class FacesConfigOrderingTestCase extends TestCase { @@ -391,7 +392,7 @@ private void populateIds(String elementName, List ids, String ns, private Document newDocument() throws ParserConfigurationException { - DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + DocumentBuilderFactory factory = createLocalDocumentBuilderFactory(); factory.setValidating(false); factory.setNamespaceAware(true); return factory.newDocumentBuilder().newDocument();