From 684d3b336e9cb31707d35e75f9b785e04e1fdbee Mon Sep 17 00:00:00 2001 From: Joe Wang Date: Mon, 21 Apr 2025 18:25:59 +0000 Subject: [PATCH] 8354774: DocumentBuilderFactory getAttribute throws NPE Reviewed-by: naoto, lancea --- .../xsltc/trax/TransformerFactoryImpl.java | 15 +- .../xerces/internal/impl/PropertyManager.java | 34 +--- .../jaxp/DocumentBuilderFactoryImpl.java | 26 +-- .../internal/jaxp/DocumentBuilderImpl.java | 15 +- .../xerces/internal/jaxp/SAXParserImpl.java | 34 +--- .../jaxp/validation/XMLSchemaFactory.java | 22 +-- .../XMLSchemaValidatorComponentManager.java | 22 +-- .../classes/jdk/xml/internal/JdkXmlUtils.java | 43 ++++- .../jdk/xml/internal/XMLSecurityManager.java | 2 +- .../jaxp/libs/jaxp/library/JUnitTestUtil.java | 13 ++ .../jaxp/unittest/common/PropertiesTest.java | 162 ++++++++++++++++++ 11 files changed, 268 insertions(+), 120 deletions(-) create mode 100644 test/jaxp/javax/xml/jaxp/unittest/common/PropertiesTest.java diff --git a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerFactoryImpl.java b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerFactoryImpl.java index 747ec8473fe..ee730d3900a 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerFactoryImpl.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerFactoryImpl.java @@ -371,17 +371,10 @@ public class TransformerFactoryImpl return _cdataChunkSize; } - /** Check to see if the property is managed by the security manager **/ - String propertyValue = (_xmlSecurityManager != null) ? - _xmlSecurityManager.getLimitAsString(name) : null; - if (propertyValue != null) { - return propertyValue; - } else { - propertyValue = (_xmlSecurityPropertyMgr != null) ? - _xmlSecurityPropertyMgr.getValue(name) : null; - if (propertyValue != null) { - return propertyValue; - } + //check if the property is managed by security manager + String value; + if ((value = JdkXmlUtils.getProperty(_xmlSecurityManager, _xmlSecurityPropertyMgr, name)) != null) { + return value; } // Throw an exception for all other attributes diff --git a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/PropertyManager.java b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/PropertyManager.java index 2167c22e001..8d83f039617 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/PropertyManager.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/PropertyManager.java @@ -27,13 +27,10 @@ package com.sun.org.apache.xerces.internal.impl; import com.sun.xml.internal.stream.StaxEntityResolverWrapper; import java.util.HashMap; import javax.xml.XMLConstants; -import javax.xml.catalog.CatalogFeatures; import javax.xml.stream.XMLInputFactory; import javax.xml.stream.XMLOutputFactory; import javax.xml.stream.XMLResolver; -import jdk.xml.internal.FeaturePropertyBase; import jdk.xml.internal.JdkConstants; -import jdk.xml.internal.JdkProperty; import jdk.xml.internal.JdkXmlUtils; import jdk.xml.internal.XMLSecurityManager; import jdk.xml.internal.XMLSecurityPropertyManager; @@ -188,20 +185,13 @@ public class PropertyManager { if (XMLInputFactory.SUPPORT_DTD.equals(property)) { return fSecurityManager.is(XMLSecurityManager.Limit.STAX_SUPPORT_DTD); } - /** - * Check to see if the property is managed by the security manager * - */ - String propertyValue = (fSecurityManager != null) - ? fSecurityManager.getLimitAsString(property) : null; - /** - * Check to see if the property is managed by the security property - * manager - */ - if (propertyValue == null) { - propertyValue = (fSecurityPropertyMgr != null) - ? fSecurityPropertyMgr.getValue(property) : null; + + //check if the property is managed by security manager + String value; + if ((value = JdkXmlUtils.getProperty(fSecurityManager, fSecurityPropertyMgr, property)) != null) { + return value; } - return propertyValue != null ? propertyValue : supportedProps.get(property); + return supportedProps.get(property); } /** @@ -250,15 +240,9 @@ public class PropertyManager { return; } - //check if the property is managed by security manager - if (fSecurityManager == null - || !fSecurityManager.setLimit(property, JdkProperty.State.APIPROPERTY, value)) { - //check if the property is managed by security property manager - if (fSecurityPropertyMgr == null - || !fSecurityPropertyMgr.setValue(property, FeaturePropertyBase.State.APIPROPERTY, value)) { - //fall back to the existing property manager - supportedProps.put(property, value); - } + if (!JdkXmlUtils.setProperty(fSecurityManager, fSecurityPropertyMgr, property, value)) { + //fall back to the existing property manager + supportedProps.put(property, value); } if (equivalentProperty != null) { diff --git a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/jaxp/DocumentBuilderFactoryImpl.java b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/jaxp/DocumentBuilderFactoryImpl.java index 6909f2b51ff..2939058e7d4 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/jaxp/DocumentBuilderFactoryImpl.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/jaxp/DocumentBuilderFactoryImpl.java @@ -29,7 +29,7 @@ import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.validation.Schema; -import jdk.xml.internal.JdkProperty; +import jdk.xml.internal.JdkXmlUtils; import jdk.xml.internal.XMLSecurityManager; import jdk.xml.internal.XMLSecurityPropertyManager; import org.xml.sax.SAXException; @@ -114,20 +114,13 @@ public class DocumentBuilderFactoryImpl extends DocumentBuilderFactory { attributes = new HashMap<>(); } - //check if the property is managed by security manager - String pName; - if ((pName = fSecurityManager.find(name)) != null) { - // as the qName is deprecated, let the manager decide whether the - // value shall be changed - fSecurityManager.setLimit(name, JdkProperty.State.APIPROPERTY, value); - attributes.put(pName, fSecurityManager.getLimitAsString(pName)); + if (JdkXmlUtils.setProperty(fSecurityManager, fSecurityPropertyMgr, name, value)) { + // necessary as DocumentBuilder recreate property manager + // remove this line once that's changed + attributes.put(name, value); // no need to create a DocumentBuilderImpl return; - } else if ((pName = fSecurityPropertyMgr.find(name)) != null) { - attributes.put(pName, value); - return; } - attributes.put(name, value); // Test the attribute name by possibly throwing an exception @@ -146,13 +139,10 @@ public class DocumentBuilderFactoryImpl extends DocumentBuilderFactory { public Object getAttribute(String name) throws IllegalArgumentException { - //check if the property is managed by security manager - String pName; - if ((pName = fSecurityManager.find(name)) != null) { - return fSecurityManager.getLimitAsString(pName); - } else if ((pName = fSecurityPropertyMgr.find(name)) != null) { - return attributes.get(pName); + String value; + if ((value = JdkXmlUtils.getProperty(fSecurityManager, fSecurityPropertyMgr, name)) != null) { + return value; } // See if it's in the attributes Map diff --git a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/jaxp/DocumentBuilderImpl.java b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/jaxp/DocumentBuilderImpl.java index a8af265c325..43b986b9939 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/jaxp/DocumentBuilderImpl.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/jaxp/DocumentBuilderImpl.java @@ -43,7 +43,7 @@ import com.sun.org.apache.xerces.internal.xni.parser.XMLDocumentSource; import com.sun.org.apache.xerces.internal.xni.parser.XMLParserConfiguration; import jdk.xml.internal.FeaturePropertyBase.State; import jdk.xml.internal.JdkConstants; -import jdk.xml.internal.JdkProperty; +import jdk.xml.internal.JdkXmlUtils; import jdk.xml.internal.XMLSecurityManager; import jdk.xml.internal.XMLSecurityPropertyManager; import jdk.xml.internal.XMLSecurityPropertyManager.Property; @@ -297,17 +297,10 @@ public class DocumentBuilderImpl extends DocumentBuilder } } } else { - //check if the property is managed by security manager - if (fSecurityManager == null || - !fSecurityManager.setLimit(name, JdkProperty.State.APIPROPERTY, val)) { - //check if the property is managed by security property manager - if (fSecurityPropertyMgr == null || - !fSecurityPropertyMgr.setValue(name, State.APIPROPERTY, val)) { - //fall back to the existing property manager - domParser.setProperty(name, val); - } + if (!JdkXmlUtils.setProperty(fSecurityManager, fSecurityPropertyMgr, name, val)) { + //fall back to the existing property manager + domParser.setProperty(name, val); } - } } } diff --git a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/jaxp/SAXParserImpl.java b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/jaxp/SAXParserImpl.java index 053718c657d..fe435aabbcc 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/jaxp/SAXParserImpl.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/jaxp/SAXParserImpl.java @@ -43,7 +43,7 @@ import javax.xml.XMLConstants; import javax.xml.validation.Schema; import jdk.xml.internal.FeaturePropertyBase; import jdk.xml.internal.JdkConstants; -import jdk.xml.internal.JdkProperty; +import jdk.xml.internal.JdkXmlUtils; import jdk.xml.internal.XMLSecurityManager; import jdk.xml.internal.XMLSecurityPropertyManager; import org.xml.sax.EntityResolver; @@ -569,20 +569,13 @@ public class SAXParserImpl extends javax.xml.parsers.SAXParser super.setProperty(name, value); } - //check if the property is managed by security manager - if (fSecurityManager == null || - !fSecurityManager.setLimit(name, JdkProperty.State.APIPROPERTY, value)) { - //check if the property is managed by security property manager - if (fSecurityPropertyMgr == null || - !fSecurityPropertyMgr.setValue(name, FeaturePropertyBase.State.APIPROPERTY, value)) { - //fall back to the existing property manager - if (!fInitProperties.containsKey(name)) { - fInitProperties.put(name, super.getProperty(name)); - } - super.setProperty(name, value); + if (!JdkXmlUtils.setProperty(fSecurityManager, fSecurityPropertyMgr, name, value)) { + //fall back to the existing property manager + if (!fInitProperties.containsKey(name)) { + fInitProperties.put(name, super.getProperty(name)); } + super.setProperty(name, value); } - } public synchronized Object getProperty(String name) @@ -596,19 +589,10 @@ public class SAXParserImpl extends javax.xml.parsers.SAXParser return fSAXParser.schemaLanguage; } - /** Check to see if the property is managed by the security manager **/ - String propertyValue = (fSecurityManager != null) ? - fSecurityManager.getLimitAsString(name) : null; - if (propertyValue != null) { - return propertyValue; - } else { - propertyValue = (fSecurityPropertyMgr != null) ? - fSecurityPropertyMgr.getValue(name) : null; - if (propertyValue != null) { - return propertyValue; - } + String value; + if ((value = JdkXmlUtils.getProperty(fSecurityManager, fSecurityPropertyMgr, name)) != null) { + return value; } - return super.getProperty(name); } diff --git a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/jaxp/validation/XMLSchemaFactory.java b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/jaxp/validation/XMLSchemaFactory.java index 753fdea25cd..82960821f4d 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/jaxp/validation/XMLSchemaFactory.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/jaxp/validation/XMLSchemaFactory.java @@ -40,7 +40,6 @@ import java.io.IOException; import java.io.InputStream; import java.io.Reader; import javax.xml.XMLConstants; -import javax.xml.catalog.CatalogFeatures.Feature; import javax.xml.stream.XMLEventReader; import javax.xml.transform.Source; import javax.xml.transform.dom.DOMSource; @@ -404,10 +403,11 @@ public final class XMLSchemaFactory extends SchemaFactory { } try { /** Check to see if the property is managed by the security manager **/ - String propertyValue = (fSecurityManager != null) ? - fSecurityManager.getLimitAsString(name) : null; - return propertyValue != null ? propertyValue : - fXMLSchemaLoader.getProperty(name); + String value; + if ((value = JdkXmlUtils.getProperty(fSecurityManager, fSecurityPropertyMgr, name)) != null) { + return value; + } + return fXMLSchemaLoader.getProperty(name); } catch (XMLConfigurationException e) { String identifier = e.getIdentifier(); @@ -513,15 +513,9 @@ public final class XMLSchemaFactory extends SchemaFactory { "property-not-supported", new Object [] {name})); } try { - //check if the property is managed by security manager - if (fSecurityManager == null || - !fSecurityManager.setLimit(name, JdkProperty.State.APIPROPERTY, object)) { - //check if the property is managed by security property manager - if (fSecurityPropertyMgr == null || - !fSecurityPropertyMgr.setValue(name, FeaturePropertyBase.State.APIPROPERTY, object)) { - //fall back to the existing property manager - fXMLSchemaLoader.setProperty(name, object); - } + if (!JdkXmlUtils.setProperty(fSecurityManager, fSecurityPropertyMgr, name, object)) { + //fall back to the existing property manager + fXMLSchemaLoader.setProperty(name, object); } } catch (XMLConfigurationException e) { diff --git a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/jaxp/validation/XMLSchemaValidatorComponentManager.java b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/jaxp/validation/XMLSchemaValidatorComponentManager.java index bb4296349eb..419bfe4b250 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/jaxp/validation/XMLSchemaValidatorComponentManager.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/jaxp/validation/XMLSchemaValidatorComponentManager.java @@ -48,7 +48,7 @@ import com.sun.org.apache.xerces.internal.xni.parser.XMLConfigurationException; import javax.xml.catalog.CatalogFeatures; import jdk.xml.internal.FeaturePropertyBase; import jdk.xml.internal.JdkConstants; -import jdk.xml.internal.JdkProperty; +import jdk.xml.internal.JdkXmlUtils; import jdk.xml.internal.XMLSecurityManager; import jdk.xml.internal.XMLSecurityPropertyManager; import org.w3c.dom.ls.LSResourceResolver; @@ -353,7 +353,7 @@ final class XMLSchemaValidatorComponentManager extends ParserConfigurationSettin * Set the state of a feature. * * @param featureId The unique identifier (URI) of the feature. - * @param state The requested state of the feature (true or false). + * @param value The value of the feature (true or false). * * @exception XMLConfigurationException If the requested feature is not known. */ @@ -361,7 +361,7 @@ final class XMLSchemaValidatorComponentManager extends ParserConfigurationSettin if (PARSER_SETTINGS.equals(featureId)) { throw new XMLConfigurationException(Status.NOT_SUPPORTED, featureId); } - else if (value == false && (VALIDATION.equals(featureId) || SCHEMA_VALIDATION.equals(featureId))) { + else if (!value && (VALIDATION.equals(featureId) || SCHEMA_VALIDATION.equals(featureId))) { throw new XMLConfigurationException(Status.NOT_SUPPORTED, featureId); } else if (USE_GRAMMAR_POOL_ONLY.equals(featureId) && value != fUseGrammarPoolOnly) { @@ -452,18 +452,12 @@ final class XMLSchemaValidatorComponentManager extends ParserConfigurationSettin fComponents.put(propertyId, value); return; } - //check if the property is managed by security manager - if (fInitSecurityManager == null || - !fInitSecurityManager.setLimit(propertyId, JdkProperty.State.APIPROPERTY, value)) { - //check if the property is managed by security property manager - if (fSecurityPropertyMgr == null || - !fSecurityPropertyMgr.setValue(propertyId, FeaturePropertyBase.State.APIPROPERTY, value)) { - //fall back to the existing property manager - if (!fInitProperties.containsKey(propertyId)) { - fInitProperties.put(propertyId, super.getProperty(propertyId)); - } - super.setProperty(propertyId, value); + if (!JdkXmlUtils.setProperty(fInitSecurityManager, fSecurityPropertyMgr, propertyId, value)) { + //fall back to the existing property manager + if (!fInitProperties.containsKey(propertyId)) { + fInitProperties.put(propertyId, super.getProperty(propertyId)); } + super.setProperty(propertyId, value); } } diff --git a/src/java.xml/share/classes/jdk/xml/internal/JdkXmlUtils.java b/src/java.xml/share/classes/jdk/xml/internal/JdkXmlUtils.java index 1654c1b6cd5..93b63a746f1 100644 --- a/src/java.xml/share/classes/jdk/xml/internal/JdkXmlUtils.java +++ b/src/java.xml/share/classes/jdk/xml/internal/JdkXmlUtils.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, 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 @@ -98,6 +98,47 @@ public class JdkXmlUtils { private static final SAXParserFactory instance = getSAXFactory(false); } + /** + * Sets the property if it's managed by either XMLSecurityManager or XMLSecurityPropertyManager. + * @param xsm the XMLSecurityManager + * @param xspm the XMLSecurityPropertyManager + * @param property the property + * @param value the value + * @return true if the property is managed by either XMLSecurityManager or + * XMLSecurityPropertyManager, false otherwise + */ + public static boolean setProperty(XMLSecurityManager xsm, XMLSecurityPropertyManager xspm, + String property, Object value) { + if (xsm != null && xsm.find(property) != null) { + return xsm.setLimit(property, JdkProperty.State.APIPROPERTY, value); + + } else if (xspm != null && xspm.find(property) != null) { + return xspm.setValue(property, FeaturePropertyBase.State.APIPROPERTY, value); + } + return false; + } + + /** + * Returns the value of the property if it's managed by either XMLSecurityManager + * or XMLSecurityPropertyManager. + * @param xsm the XMLSecurityManager + * @param xspm the XMLSecurityPropertyManager + * @param property the property + * @return the value of the property if it's managed by either XMLSecurityManager + * or XMLSecurityPropertyManager, null otherwise + */ + public static String getProperty(XMLSecurityManager xsm, XMLSecurityPropertyManager xspm, + String property) { + String value = null; + if (xsm != null && (value = xsm.getLimitAsString(property)) != null) { + return value; + } + if (xspm != null) { + value = xspm.getValue(property); + } + return value; + } + /** * Returns the value. * diff --git a/src/java.xml/share/classes/jdk/xml/internal/XMLSecurityManager.java b/src/java.xml/share/classes/jdk/xml/internal/XMLSecurityManager.java index 394bf28e02a..90c222de40e 100644 --- a/src/java.xml/share/classes/jdk/xml/internal/XMLSecurityManager.java +++ b/src/java.xml/share/classes/jdk/xml/internal/XMLSecurityManager.java @@ -361,7 +361,7 @@ public final class XMLSecurityManager { for (Limit limit : Limit.values()) { if (limit.is(propertyName)) { // current spec: new property name == systemProperty - return limit.systemProperty(); + return (limit.systemProperty != null) ? limit.systemProperty : limit.apiProperty; } } //ENTITYCOUNT's new name is qName diff --git a/test/jaxp/javax/xml/jaxp/libs/jaxp/library/JUnitTestUtil.java b/test/jaxp/javax/xml/jaxp/libs/jaxp/library/JUnitTestUtil.java index a31963f21de..f4eb3188242 100644 --- a/test/jaxp/javax/xml/jaxp/libs/jaxp/library/JUnitTestUtil.java +++ b/test/jaxp/javax/xml/jaxp/libs/jaxp/library/JUnitTestUtil.java @@ -32,6 +32,19 @@ public class JUnitTestUtil { public static final String CLS_DIR = System.getProperty("test.classes"); public static final String SRC_DIR = System.getProperty("test.src"); + // as in the Processors table in java.xml module summary + public enum Processor { + DOM, + SAX, + XMLREADER, + StAX, + VALIDATION, + TRANSFORM, + XSLTC, + DOMLS, + XPATH + }; + /** * Returns the System identifier (URI) of the source. * @param path the path to the source diff --git a/test/jaxp/javax/xml/jaxp/unittest/common/PropertiesTest.java b/test/jaxp/javax/xml/jaxp/unittest/common/PropertiesTest.java new file mode 100644 index 00000000000..1550c53794a --- /dev/null +++ b/test/jaxp/javax/xml/jaxp/unittest/common/PropertiesTest.java @@ -0,0 +1,162 @@ +/* + * Copyright (c) 2025, 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package common; + +import javax.xml.XMLConstants; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.SAXParser; +import javax.xml.parsers.SAXParserFactory; +import javax.xml.stream.XMLInputFactory; +import javax.xml.transform.TransformerFactory; +import javax.xml.validation.SchemaFactory; +import java.util.EnumSet; +import java.util.Set; +import java.util.stream.Stream; +import jaxp.library.JUnitTestUtil.Processor; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.xml.sax.XMLReader; +import static org.junit.jupiter.api.Assertions.assertEquals; + +/* + * @test + * @bug 8354774 + * @summary Verifies JAXP API Properties as specified in the java.xml module. + * @library /javax/xml/jaxp/libs /javax/xml/jaxp/unittest /test/lib + * @run junit/othervm common.PropertiesTest + */ +public class PropertiesTest { + private static final String ACCESS_EXTERNAL_DTD = XMLConstants.ACCESS_EXTERNAL_DTD; + private static final String ACCESS_EXTERNAL_SCHEMA = XMLConstants.ACCESS_EXTERNAL_SCHEMA; + private static final String ACCESS_EXTERNAL_STYLESHEET = XMLConstants.ACCESS_EXTERNAL_STYLESHEET; + private static final String SP_ACCESS_EXTERNAL_DTD = "javax.xml.accessExternalDTD"; + private static final String SP_ACCESS_EXTERNAL_SCHEMA = "javax.xml.accessExternalSchema"; + private static final String SP_ACCESS_EXTERNAL_STYLESHEET = "javax.xml.accessExternalStylesheet"; + private static final String DEFAULT_VALUE = "all"; + /** + * Returns test data for testAccessExternalProperties + * @return test data for testAccessExternalProperties + */ + private static Stream testData() { + // Supported processors for Access External Properties + Set supportedProcessors1 = EnumSet.of(Processor.DOM, Processor.SAX, Processor.XMLREADER, + Processor.StAX, Processor.VALIDATION); + Set supportedProcessors2 = EnumSet.of(Processor.TRANSFORM); + + return Stream.of( + Arguments.of(supportedProcessors1, ACCESS_EXTERNAL_DTD, null, SP_ACCESS_EXTERNAL_DTD, null, DEFAULT_VALUE), + Arguments.of(supportedProcessors1, ACCESS_EXTERNAL_DTD, "http", SP_ACCESS_EXTERNAL_DTD, null, "http"), + Arguments.of(supportedProcessors1, ACCESS_EXTERNAL_DTD, null, SP_ACCESS_EXTERNAL_DTD, "https", "https"), + Arguments.of(supportedProcessors1, ACCESS_EXTERNAL_DTD, "http", SP_ACCESS_EXTERNAL_DTD, "https", "http"), + Arguments.of(supportedProcessors1, ACCESS_EXTERNAL_SCHEMA, null, SP_ACCESS_EXTERNAL_SCHEMA, null, DEFAULT_VALUE), + Arguments.of(supportedProcessors1, ACCESS_EXTERNAL_SCHEMA, "http", SP_ACCESS_EXTERNAL_SCHEMA, null, "http"), + Arguments.of(supportedProcessors1, ACCESS_EXTERNAL_SCHEMA, null, SP_ACCESS_EXTERNAL_SCHEMA, "https", "https"), + Arguments.of(supportedProcessors1, ACCESS_EXTERNAL_SCHEMA, "http", SP_ACCESS_EXTERNAL_SCHEMA, "https", "http"), + Arguments.of(supportedProcessors2, ACCESS_EXTERNAL_STYLESHEET, null, SP_ACCESS_EXTERNAL_STYLESHEET, null, DEFAULT_VALUE), + Arguments.of(supportedProcessors2, ACCESS_EXTERNAL_STYLESHEET, "http", SP_ACCESS_EXTERNAL_STYLESHEET, null, "http"), + Arguments.of(supportedProcessors2, ACCESS_EXTERNAL_STYLESHEET, null, SP_ACCESS_EXTERNAL_STYLESHEET, "https", "https"), + Arguments.of(supportedProcessors2, ACCESS_EXTERNAL_STYLESHEET, "http", SP_ACCESS_EXTERNAL_STYLESHEET, "https", "http") + ); + } + + /** + * Verifies that the Access External Properties are supported throughout the + * JAXP APIs. + * @param supportedProcessors the supported processors for the property + * @param apiProperty the API property + * @param apiValue the value of the API property + * @param sysProperty the System property corresponding to the API property + * @param sysValue the value of the System property + * @param expected the expected result + * @throws Exception if the test fails due to test configuration issues other + * than the expected result + */ + @ParameterizedTest + @MethodSource("testData") + public void testAccessExternalProperties(Set supportedProcessors, + String apiProperty, String apiValue, String sysProperty, String sysValue, + String expected) throws Exception { + for (Processor p : supportedProcessors) { + testProperties(p, apiProperty, apiValue, sysProperty, sysValue, + expected); + } + } + + /** + * Verifies that properties can be set via the JAXP APIs and their corresponding + * System Properties. + * @param processor the processor type + * @param apiProperty the API property + * @param apiValue the value to be set via the API property + * @param sysProperty the System Property + * @param sysValue the value to be set via the System property + * @param expected the expected result + * @throws Exception if the test fails, which can only happen if the property + * is set incorrectly. + */ + void testProperties(Processor processor, String apiProperty, String apiValue, + String sysProperty, String sysValue, String expected) + throws Exception { + Object ret1 = null; + if (sysValue != null) { + System.setProperty(sysProperty, sysValue); + } + switch (processor) { + case DOM: + DocumentBuilderFactory dbf = DocumentBuilderFactory.newDefaultInstance(); + if (apiValue != null) dbf.setAttribute(apiProperty, apiValue); + ret1 = dbf.getAttribute(apiProperty); + break; + case SAX: + SAXParser sp = SAXParserFactory.newDefaultInstance().newSAXParser(); + if (apiValue != null) sp.setProperty(apiProperty, apiValue); + ret1 = sp.getProperty(apiProperty); + break; + case XMLREADER: + XMLReader reader = SAXParserFactory.newDefaultInstance().newSAXParser().getXMLReader(); + if (apiValue != null) reader.setProperty(apiProperty, apiValue); + ret1 = reader.getProperty(apiProperty); + break; + case StAX: + XMLInputFactory xif = XMLInputFactory.newDefaultFactory(); + if (apiValue != null) xif.setProperty(apiProperty, apiValue); + ret1 = xif.getProperty(apiProperty); + break; + case VALIDATION: + SchemaFactory sf = SchemaFactory.newDefaultInstance(); + if (apiValue != null) sf.setProperty(apiProperty, apiValue); + ret1 = sf.getProperty(apiProperty); + break; + case TRANSFORM: + TransformerFactory tf = TransformerFactory.newDefaultInstance(); + if (apiValue != null) tf.setAttribute(apiProperty, apiValue); + ret1 = tf.getAttribute(apiProperty); + break; + } + + if (sysValue != null) System.clearProperty(sysProperty); + // property value is as expected + assertEquals(expected, ret1); + } +}