From 93bdc2a6db91a95d6ee52ec92080e586c694dad5 Mon Sep 17 00:00:00 2001 From: Joe Wang Date: Wed, 22 Nov 2023 17:11:26 +0000 Subject: [PATCH] 8306055: Add a built-in Catalog to JDK XML module Reviewed-by: ihse, lancea, alanb --- make/modules/java.xml/Java.gmk | 1 + .../xerces/internal/impl/PropertyManager.java | 7 +- .../impl/XMLDocumentFragmentScannerImpl.java | 9 +- .../internal/impl/XMLDocumentScannerImpl.java | 9 +- .../internal/impl/XMLEntityManager.java | 251 ++++++------ .../xerces/internal/jaxp/SAXParserImpl.java | 4 +- .../jaxp/validation/XMLSchemaFactory.java | 3 - .../xerces/internal/parsers/SAXParser.java | 36 +- .../XIncludeAwareParserConfiguration.java | 24 +- .../internal/parsers/XML11Configuration.java | 31 +- .../xerces/internal/parsers/XMLParser.java | 31 +- .../util/ParserConfigurationSettings.java | 7 +- .../share/classes/javax/xml/catalog/Util.java | 2 +- .../classes/jdk/xml/internal/JdkCatalog.java | 46 +++ .../jdk/xml/internal/JdkConstants.java | 12 + .../classes/jdk/xml/internal/JdkXmlUtils.java | 26 ++ .../jdk/xml/internal/SecuritySupport.java | 41 ++ .../jdk/xml/internal/XMLSecurityManager.java | 64 +++- .../xml/internal/jdkcatalog/JDKCatalog.xml | 41 ++ .../jdkcatalog/java/dtd/preferences.dtd | 110 ++++++ .../jdkcatalog/java/dtd/properties.dtd | 15 + src/java.xml/share/classes/module-info.java | 68 +++- .../libs/jaxp/library/JAXPPolicyManager.java | 4 +- .../unittest/catalog/CatalogSupportBase.java | 19 +- .../common/catalog/CatalogTestBase.java | 361 ++++++++++++++++++ .../jaxp/unittest/common/catalog/DOMTest.java | 51 +++ .../jaxp/unittest/common/catalog/SAXTest.java | 51 +++ .../unittest/common/catalog/SchemaTest.java | 66 ++++ .../unittest/common/catalog/StAXTest.java | 51 +++ .../common/catalog/TransformTest.java | 58 +++ .../catalog/testcatalog/TestCatalog.xml | 32 ++ .../catalog/testcatalog/dtds/XSLDTD.dtd | 108 ++++++ .../catalog/testcatalog/dtds/paramEntity.dtd | 2 + .../common/catalog/testcatalog/dtds/test.dtd | 6 + .../catalog/testcatalog/xinclude/XI_red.dtd | 4 + .../testcatalog/xinclude/XI_simple.xml | 18 + .../catalog/testcatalog/xinclude/XI_test2.xml | 10 + .../catalog/testcatalog/xinclude/XI_utf8.xml | 4 + .../testcatalog/xsds/XSDImport_person.xsd | 12 + .../testcatalog/xsds/XSDImport_product.xsd | 11 + .../testcatalog/xsds/XSDInclude_person.xsd | 12 + .../testcatalog/xsds/XSDInclude_product.xsd | 11 + .../catalog/testcatalog/xsds/val_test.xsd | 16 + .../common/config/files/catalog2.properties | 36 ++ .../common/config/files/jaxp.properties | 5 + .../jaxp/unittest/common/dtd/DTDTestBase.java | 9 - .../jaxp/unittest/common/util/TestBase.java | 127 +++++- .../unittest/common/xmlfiles/XI_roottest.xml | 6 + .../jaxp/unittest/common/xmlfiles/test.xml | 6 + .../common/xmlfiles/testExternalParameter.xml | 12 + 50 files changed, 1730 insertions(+), 216 deletions(-) create mode 100644 src/java.xml/share/classes/jdk/xml/internal/JdkCatalog.java create mode 100644 src/java.xml/share/classes/jdk/xml/internal/jdkcatalog/JDKCatalog.xml create mode 100644 src/java.xml/share/classes/jdk/xml/internal/jdkcatalog/java/dtd/preferences.dtd create mode 100644 src/java.xml/share/classes/jdk/xml/internal/jdkcatalog/java/dtd/properties.dtd create mode 100644 test/jaxp/javax/xml/jaxp/unittest/common/catalog/CatalogTestBase.java create mode 100644 test/jaxp/javax/xml/jaxp/unittest/common/catalog/DOMTest.java create mode 100644 test/jaxp/javax/xml/jaxp/unittest/common/catalog/SAXTest.java create mode 100644 test/jaxp/javax/xml/jaxp/unittest/common/catalog/SchemaTest.java create mode 100644 test/jaxp/javax/xml/jaxp/unittest/common/catalog/StAXTest.java create mode 100644 test/jaxp/javax/xml/jaxp/unittest/common/catalog/TransformTest.java create mode 100644 test/jaxp/javax/xml/jaxp/unittest/common/catalog/testcatalog/TestCatalog.xml create mode 100644 test/jaxp/javax/xml/jaxp/unittest/common/catalog/testcatalog/dtds/XSLDTD.dtd create mode 100644 test/jaxp/javax/xml/jaxp/unittest/common/catalog/testcatalog/dtds/paramEntity.dtd create mode 100644 test/jaxp/javax/xml/jaxp/unittest/common/catalog/testcatalog/dtds/test.dtd create mode 100644 test/jaxp/javax/xml/jaxp/unittest/common/catalog/testcatalog/xinclude/XI_red.dtd create mode 100644 test/jaxp/javax/xml/jaxp/unittest/common/catalog/testcatalog/xinclude/XI_simple.xml create mode 100644 test/jaxp/javax/xml/jaxp/unittest/common/catalog/testcatalog/xinclude/XI_test2.xml create mode 100644 test/jaxp/javax/xml/jaxp/unittest/common/catalog/testcatalog/xinclude/XI_utf8.xml create mode 100644 test/jaxp/javax/xml/jaxp/unittest/common/catalog/testcatalog/xsds/XSDImport_person.xsd create mode 100644 test/jaxp/javax/xml/jaxp/unittest/common/catalog/testcatalog/xsds/XSDImport_product.xsd create mode 100644 test/jaxp/javax/xml/jaxp/unittest/common/catalog/testcatalog/xsds/XSDInclude_person.xsd create mode 100644 test/jaxp/javax/xml/jaxp/unittest/common/catalog/testcatalog/xsds/XSDInclude_product.xsd create mode 100644 test/jaxp/javax/xml/jaxp/unittest/common/catalog/testcatalog/xsds/val_test.xsd create mode 100644 test/jaxp/javax/xml/jaxp/unittest/common/config/files/catalog2.properties create mode 100644 test/jaxp/javax/xml/jaxp/unittest/common/xmlfiles/XI_roottest.xml create mode 100644 test/jaxp/javax/xml/jaxp/unittest/common/xmlfiles/test.xml create mode 100644 test/jaxp/javax/xml/jaxp/unittest/common/xmlfiles/testExternalParameter.xml diff --git a/make/modules/java.xml/Java.gmk b/make/modules/java.xml/Java.gmk index 7d64387548b..70ae7600663 100644 --- a/make/modules/java.xml/Java.gmk +++ b/make/modules/java.xml/Java.gmk @@ -27,4 +27,5 @@ DISABLED_WARNINGS_java += lossy-conversions this-escape DOCLINT += -Xdoclint:all/protected \ '-Xdoclint/package:$(call CommaList, javax.xml.catalog javax.xml.datatype \ javax.xml.transform javax.xml.validation javax.xml.xpath)' +COPY += .dtd .xsd .xml CLEAN += .properties 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 92b81685a94..da21fb4a511 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 @@ -46,7 +46,7 @@ import jdk.xml.internal.XMLSecurityManager; * @author K Venugopal * @author Sunitha Reddy * - * @LastModified: July 2023 + * @LastModified: Nov 2023 */ public class PropertyManager { @@ -150,10 +150,7 @@ public class PropertyManager { // Initialize Catalog features supportedProps.put(XMLConstants.USE_CATALOG, JdkXmlUtils.USE_CATALOG_DEFAULT); - for (CatalogFeatures.Feature f : CatalogFeatures.Feature.values()) { - supportedProps.put(f.getPropertyName(), null); - } - + JdkXmlUtils.initCatalogFeatures(supportedProps); supportedProps.put(JdkConstants.CDATA_CHUNK_SIZE, JdkConstants.CDATA_CHUNK_SIZE_DEFAULT); } diff --git a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLDocumentFragmentScannerImpl.java b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLDocumentFragmentScannerImpl.java index 8f55114af33..b77108b1e0e 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLDocumentFragmentScannerImpl.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLDocumentFragmentScannerImpl.java @@ -74,7 +74,7 @@ import jdk.xml.internal.XMLSecurityManager.Limit; * @author Eric Ye, IBM * @author Sunitha Reddy, SUN Microsystems * - * @LastModified: July 2023 + * @LastModified: Nov 2023 */ public class XMLDocumentFragmentScannerImpl extends XMLScanner @@ -343,6 +343,13 @@ public class XMLDocumentFragmentScannerImpl */ protected String fAccessExternalDTD = EXTERNAL_ACCESS_DEFAULT; + /** + * Properties to determine whether to use a user-specified Catalog: + * Feature USE_CATALOG, Resolve and Catalog File + */ + protected boolean fUseCatalog = true; + protected String fCatalogFile; + /** * standard uri conformant (strict uri). * http://apache.org/xml/features/standard-uri-conformant diff --git a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLDocumentScannerImpl.java b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLDocumentScannerImpl.java index f859a499d29..52bfcd7aeec 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLDocumentScannerImpl.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLDocumentScannerImpl.java @@ -43,9 +43,11 @@ import com.sun.xml.internal.stream.dtd.DTDGrammarUtil; import java.io.CharConversionException; import java.io.EOFException; import java.io.IOException; +import javax.xml.XMLConstants; import javax.xml.stream.events.XMLEvent; import jdk.xml.internal.JdkConstants; import jdk.xml.internal.JdkProperty.State; +import jdk.xml.internal.JdkXmlUtils; import jdk.xml.internal.SecuritySupport; import jdk.xml.internal.XMLSecurityManager.Limit; @@ -69,7 +71,7 @@ import jdk.xml.internal.XMLSecurityManager.Limit; * Refer to the table in unit-test javax.xml.stream.XMLStreamReaderTest.SupportDTD for changes * related to property SupportDTD. * @author Joe Wang, Sun Microsystems - * @LastModified: July 2023 + * @LastModified: Nov 2023 */ public class XMLDocumentScannerImpl extends XMLDocumentFragmentScannerImpl{ @@ -281,6 +283,9 @@ public class XMLDocumentScannerImpl fLoadExternalDTD = !((Boolean)propertyManager.getProperty( Constants.ZEPHYR_PROPERTY_PREFIX + Constants.IGNORE_EXTERNAL_DTD)); + fUseCatalog = (Boolean)propertyManager.getProperty(XMLConstants.USE_CATALOG); + fCatalogFile = (String)propertyManager.getProperty(JdkXmlUtils.CATALOG_FILES); + setScannerState(XMLEvent.START_DOCUMENT); setDriver(fXMLDeclDriver); fSeenInternalSubset = false; @@ -327,6 +332,8 @@ public class XMLDocumentScannerImpl // xerces features fLoadExternalDTD = componentManager.getFeature(LOAD_EXTERNAL_DTD, true); + fUseCatalog = componentManager.getFeature(XMLConstants.USE_CATALOG, true); + fCatalogFile = (String)componentManager.getProperty(JdkXmlUtils.CATALOG_FILES); fNamespaces = componentManager.getFeature(NAMESPACES, true); fSeenInternalSubset = false; diff --git a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLEntityManager.java b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLEntityManager.java index d127f7c8ec1..22de24ea8f0 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLEntityManager.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLEntityManager.java @@ -56,6 +56,7 @@ import javax.xml.catalog.CatalogManager; import javax.xml.catalog.CatalogResolver; import javax.xml.stream.XMLInputFactory; import javax.xml.transform.Source; +import jdk.xml.internal.JdkCatalog; import jdk.xml.internal.JdkConstants; import jdk.xml.internal.JdkProperty; import jdk.xml.internal.JdkXmlUtils; @@ -93,7 +94,7 @@ import org.xml.sax.InputSource; * @author K.Venugopal SUN Microsystems * @author Neeraj Bajaj SUN Microsystems * @author Sunitha Reddy SUN Microsystems - * @LastModified: July 2023 + * @LastModified: Nov 2023 */ public class XMLEntityManager implements XMLComponent, XMLEntityResolver { @@ -265,9 +266,6 @@ public class XMLEntityManager implements XMLComponent, XMLEntityResolver { /** Debug switching readers for encodings. */ private static final boolean DEBUG_ENCODINGS = false; - // should be diplayed trace resolving messages - private static final boolean DEBUG_RESOLVER = false ; - // // Data // @@ -355,6 +353,7 @@ public class XMLEntityManager implements XMLComponent, XMLEntityResolver { /** Security Manager */ protected XMLSecurityManager fSecurityManager = null; + XMLSecurityPropertyManager fSecurityPropertyMgr; protected XMLLimitAnalyzer fLimitAnalyzer = null; @@ -418,8 +417,11 @@ public class XMLEntityManager implements XMLComponent, XMLEntityResolver { /** indicate whether Catalog should be used for resolving external resources */ private boolean fUseCatalog = true; + // user-specified Catalog Resolver CatalogFeatures fCatalogFeatures; CatalogResolver fCatalogResolver; + // the default JDK Catalog Resolver + CatalogResolver fDefCR; private String fCatalogFile; private String fDefer; @@ -434,11 +436,16 @@ public class XMLEntityManager implements XMLComponent, XMLEntityResolver { * If this constructor is used to create the object, reset() should be invoked on this object */ public XMLEntityManager() { + this(null, new XMLSecurityManager(true)); + } + + public XMLEntityManager(XMLSecurityPropertyManager securityPropertyMgr, XMLSecurityManager securityManager) { //for entity managers not created by parsers - fSecurityManager = new XMLSecurityManager(true); + fSecurityManager = securityManager; + fSecurityPropertyMgr = securityPropertyMgr; fEntityStorage = new XMLEntityStorage(this) ; setScannerVersion(Constants.XML_VERSION_1_0); - } // () + } /** Default constructor. */ public XMLEntityManager(PropertyManager propertyManager) { @@ -653,7 +660,11 @@ public class XMLEntityManager implements XMLComponent, XMLEntityResolver { URL location = new URL(expandedSystemId); URLConnection connect = location.openConnection(); if (!(connect instanceof HttpURLConnection)) { - stream = connect.getInputStream(); + if (expandedSystemId.startsWith("jrt:/java.xml")) { + stream = SecuritySupport.getInputStream(connect); + } else { + stream = connect.getInputStream(); + } } else { boolean followRedirects = true; @@ -1012,75 +1023,128 @@ public class XMLEntityManager implements XMLComponent, XMLEntityResolver { ri = fResourceIdentifier; } ri.setValues(publicId, literalSystemId, baseSystemId, expandedSystemId); - if(DEBUG_RESOLVER){ - System.out.println("BEFORE Calling resolveEntity") ; - } fISCreatedByResolver = false; - //either of Stax or Xerces would be null - if(fStaxEntityResolver != null){ + // Step 1: custom resolver, either StAX or Entity + if (fStaxEntityResolver != null) { staxInputSource = fStaxEntityResolver.resolveEntity(ri); - if(staxInputSource != null) { - fISCreatedByResolver = true; - } - } - - if(fEntityResolver != null){ + } else if (fEntityResolver != null) { xmlInputSource = fEntityResolver.resolveEntity(ri); - if(xmlInputSource != null) { + if (xmlInputSource != null) { + //wrap it in StaxXMLInputSource fISCreatedByResolver = true; + staxInputSource = new StaxXMLInputSource(xmlInputSource, fISCreatedByResolver); } } - if(xmlInputSource != null){ - //wrap this XMLInputSource to StaxInputSource - staxInputSource = new StaxXMLInputSource(xmlInputSource, fISCreatedByResolver); - } - - if (staxInputSource == null && fUseCatalog) { - if (fCatalogFeatures == null) { + // Step 2: custom catalog if specified + if (staxInputSource == null && (fUseCatalog && fCatalogFile != null)) { + if (fCatalogResolver == null) { fCatalogFeatures = JdkXmlUtils.getCatalogFeatures(fDefer, fCatalogFile, fPrefer, fResolve); + fCatalogResolver = CatalogManager.catalogResolver(fCatalogFeatures); } - fCatalogFile = fCatalogFeatures.get(Feature.FILES); - if (fCatalogFile != null) { - try { - if (fCatalogResolver == null) { - fCatalogResolver = CatalogManager.catalogResolver(fCatalogFeatures); - } - InputSource is = fCatalogResolver.resolveEntity(publicId, literalSystemId); - if (is != null && !is.isEmpty()) { - staxInputSource = new StaxXMLInputSource(new XMLInputSource(is, true), true); - } - } catch (CatalogException e) { - fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN,"CatalogException", - new Object[]{SecuritySupport.sanitizePath(fCatalogFile)}, - XMLErrorReporter.SEVERITY_FATAL_ERROR, e ); - } - } + + staxInputSource = resolveWithCatalogStAX(fCatalogResolver, fCatalogFile, publicId, literalSystemId); } - // do default resolution - //this works for both stax & Xerces, if staxInputSource is null, - //it means parser need to revert to default resolution - if (staxInputSource == null) { - // REVISIT: when systemId is null, I think we should return null. - // is this the right solution? -SG - //if (systemId != null) + // Step 3: use the default JDK Catalog Resolver if Step 2's resolve is continue + if (staxInputSource == null && JdkXmlUtils.isResolveContinue(fCatalogFeatures)) { + initJdkCatalogResolver(); + + staxInputSource = resolveWithCatalogStAX(fDefCR, JdkCatalog.JDKCATALOG, publicId, literalSystemId); + } + + // Step 4: default resolution if not resolved by a resolver and the RESOLVE + // feature is set to 'continue' + if (staxInputSource != null) { + fISCreatedByResolver = true; + } else if (JdkXmlUtils.isResolveContinue(fCatalogFeatures) && + fSecurityManager.is(Limit.JDKCATALOG_RESOLVE, JdkConstants.CONTINUE)) { staxInputSource = new StaxXMLInputSource( new XMLInputSource(publicId, literalSystemId, baseSystemId, true), false); - }else if(staxInputSource.hasXMLStreamOrXMLEventReader()){ - //Waiting for the clarification from EG. - nb - } - - if (DEBUG_RESOLVER) { - System.err.println("XMLEntityManager.resolveEntity(" + publicId + ")"); - System.err.println(" = " + xmlInputSource); } return staxInputSource; } + private void initJdkCatalogResolver() { + if (fDefCR == null) { + fDefCR = fSecurityManager.getJDKCatalogResolver(); + } + } + + /** + * Resolves the external resource using the Catalog specified and returns + * a StaxXMLInputSource. + */ + private StaxXMLInputSource resolveWithCatalogStAX(CatalogResolver cr, String cFile, + String publicId, String systemId) { + InputSource is = resolveWithCatalog(cr, cFile, publicId, systemId); + // note that empty source isn't considered resolved + if (is != null) { + return new StaxXMLInputSource(new XMLInputSource(is, true), true); + } + return null; + } + + /** + * Resolves the external resource using the Catalog specified and returns + * a InputSource. + */ + private InputSource resolveWithCatalog(CatalogResolver cr, String cFile, + String publicId, String systemId) { + if (cr != null) { + try { + return cr.resolveEntity(publicId, systemId); + } catch (CatalogException e) { + fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN,"CatalogException", + new Object[]{SecuritySupport.sanitizePath(cFile)}, + XMLErrorReporter.SEVERITY_FATAL_ERROR, e ); + } + } + return null; + } + + /** + * Resolves the external resource using the Catalog specified and returns + * a XMLInputSource. Since the Resolve method can be called from various processors, + * this method attempts to resolve the resource as an EntityResolver first + * and then URIResolver if no match is found. + */ + private XMLInputSource resolveEntityOrURI(CatalogResolver cr, String publicId, String systemId, String base) { + XMLInputSource xis = resolveEntity(cr, publicId, systemId, base); + + if (xis != null) { + return xis; + } else if (systemId != null) { + Source source = null; + try { + source = cr.resolve(systemId, base); + } catch (CatalogException e) { + throw new XNIException(e); + } + if (source != null && !source.isEmpty()) { + return new XMLInputSource(publicId, source.getSystemId(), base, true); + } + } + return null; + } + + private XMLInputSource resolveEntity(CatalogResolver cr, String publicId, String systemId, String base) { + InputSource is = null; + try { + if (publicId != null || systemId != null) { + is = cr.resolveEntity(publicId, systemId); + } + } catch (CatalogException e) {} + + if (is != null && !is.isEmpty()) { + return new XMLInputSource(is, true); + } + return null; + } + /** * Resolves the specified public and system identifiers. This * method first attempts to resolve the entity based on the @@ -1128,7 +1192,7 @@ public class XMLEntityManager implements XMLComponent, XMLEntityResolver { if (needExpand) expandedSystemId = expandSystemId(literalSystemId, baseSystemId,false); - // give the entity resolver a chance + // Step 1: custom Entity resolver XMLInputSource xmlInputSource = null; if (fEntityResolver != null) { @@ -1137,65 +1201,32 @@ public class XMLEntityManager implements XMLComponent, XMLEntityResolver { xmlInputSource = fEntityResolver.resolveEntity(resourceIdentifier); } - if (xmlInputSource == null && fUseCatalog) { - if (fCatalogFeatures == null) { + // Step 2: custom catalog if specified + if ((publicId != null || literalSystemId != null || resourceIdentifier.getNamespace() !=null) + && xmlInputSource == null && (fUseCatalog && fCatalogFile != null)) { + if (fCatalogResolver == null) { fCatalogFeatures = JdkXmlUtils.getCatalogFeatures(fDefer, fCatalogFile, fPrefer, fResolve); + fCatalogResolver = CatalogManager.catalogResolver(fCatalogFeatures); } - fCatalogFile = fCatalogFeatures.get(Feature.FILES); - if (fCatalogFile != null) { - /* - since the method can be called from various processors, both - EntityResolver and URIResolver are used to attempt to find - a match - */ - InputSource is = null; - try { - if (fCatalogResolver == null) { - fCatalogResolver = CatalogManager.catalogResolver(fCatalogFeatures); - } - String pid = (publicId != null? publicId : resourceIdentifier.getNamespace()); - if (pid != null || literalSystemId != null) { - is = fCatalogResolver.resolveEntity(pid, literalSystemId); - } - } catch (CatalogException e) {} - - if (is != null && !is.isEmpty()) { - xmlInputSource = new XMLInputSource(is, true); - } else if (literalSystemId != null) { - if (fCatalogResolver == null) { - fCatalogResolver = CatalogManager.catalogResolver(fCatalogFeatures); - } - - Source source = null; - try { - source = fCatalogResolver.resolve(literalSystemId, baseSystemId); - } catch (CatalogException e) { - throw new XNIException(e); - } - if (source != null && !source.isEmpty()) { - xmlInputSource = new XMLInputSource(publicId, source.getSystemId(), baseSystemId, true); - } - } - } + String pid = (publicId != null? publicId : resourceIdentifier.getNamespace()); + xmlInputSource = resolveEntityOrURI(fCatalogResolver, pid, literalSystemId, baseSystemId); } - // do default resolution - // REVISIT: what's the correct behavior if the user provided an entity - // resolver (fEntityResolver != null), but resolveEntity doesn't return - // an input source (xmlInputSource == null)? - // do we do default resolution, or do we just return null? -SG - if (xmlInputSource == null) { - // REVISIT: when systemId is null, I think we should return null. - // is this the right solution? -SG - //if (systemId != null) + // Step 3: use the default JDK Catalog Resolver if Step 2's resolve is continue + if ((publicId != null || literalSystemId != null) + && xmlInputSource == null && JdkXmlUtils.isResolveContinue(fCatalogFeatures)) { + initJdkCatalogResolver(); + // unlike a custom catalog, the JDK Catalog only contains entity references + xmlInputSource = resolveEntity(fDefCR, publicId, literalSystemId, baseSystemId); + } + + // Step 4: default resolution if not resolved by a resolver and the RESOLVE + // feature is set to 'continue' + if ((xmlInputSource == null) && JdkXmlUtils.isResolveContinue(fCatalogFeatures) && + fSecurityManager.is(Limit.JDKCATALOG_RESOLVE, JdkConstants.CONTINUE)) { xmlInputSource = new XMLInputSource(publicId, literalSystemId, baseSystemId, false); } - if (DEBUG_RESOLVER) { - System.err.println("XMLEntityManager.resolveEntity(" + publicId + ")"); - System.err.println(" = " + xmlInputSource); - } - return xmlInputSource; } // resolveEntity(XMLResourceIdentifier):XMLInputSource @@ -1411,7 +1442,7 @@ public class XMLEntityManager implements XMLComponent, XMLEntityResolver { fSecurityManager.debugPrint(fLimitAnalyzer); fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN,"EntityExpansionLimit", new Object[]{fSecurityManager.getLimitValueByIndex(entityExpansionIndex)}, - XMLErrorReporter.SEVERITY_FATAL_ERROR ); + XMLErrorReporter.SEVERITY_FATAL_ERROR ); // is there anything better to do than reset the counter? // at least one can envision debugging applications where this might // be useful... 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 c0ae87c08a6..e5dd8a3c25e 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 @@ -63,7 +63,7 @@ import org.xml.sax.helpers.DefaultHandler; * @author Rajiv Mordani * @author Edwin Goei * - * @LastModified: July 2023 + * @LastModified: Nov 2023 */ @SuppressWarnings("deprecation") public class SAXParserImpl extends javax.xml.parsers.SAXParser @@ -402,7 +402,7 @@ public class SAXParserImpl extends javax.xml.parsers.SAXParser JAXPSAXParser(SAXParserImpl saxParser, XMLSecurityPropertyManager securityPropertyMgr, XMLSecurityManager securityManager) { - super(); + super(null, null, securityPropertyMgr, securityManager); fSAXParser = saxParser; fSecurityManager = securityManager; fSecurityPropertyMgr = securityPropertyMgr; 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 bb1eb23284d..f36d2bd14bb 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 @@ -162,9 +162,6 @@ public final class XMLSchemaFactory extends SchemaFactory { // use catalog fXMLSchemaLoader.setFeature(XMLConstants.USE_CATALOG, JdkXmlUtils.USE_CATALOG_DEFAULT); - for (Feature f : Feature.values()) { - fXMLSchemaLoader.setProperty(f.getPropertyName(), null); - } fXMLSchemaLoader.setProperty(JdkConstants.CDATA_CHUNK_SIZE, JdkConstants.CDATA_CHUNK_SIZE_DEFAULT); fXmlFeatures = new JdkXmlFeatures(fSecurityManager.isSecureProcessing()); diff --git a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/parsers/SAXParser.java b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/parsers/SAXParser.java index e8fd5424265..a71c8cc56d1 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/parsers/SAXParser.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/parsers/SAXParser.java @@ -41,7 +41,7 @@ import org.xml.sax.SAXNotSupportedException; * @author Arnaud Le Hors, IBM * @author Andy Clark, IBM * - * @LastModified: Sep 2023 + * @LastModified: Nov 2023 */ public class SAXParser extends AbstractSAXParser { @@ -91,21 +91,21 @@ public class SAXParser */ public SAXParser(XMLParserConfiguration config) { super(config); - initSecurityManager(); + initSecurityManager(null, null); } // (XMLParserConfiguration) /** * Constructs a SAX parser using the dtd/xml schema parser configuration. */ public SAXParser() { - this(null, null); + this(null, null, null, null); } // () /** * Constructs a SAX parser using the specified symbol table. */ public SAXParser(SymbolTable symbolTable) { - this(symbolTable, null); + this(symbolTable, null, null, null); } // (SymbolTable) /** @@ -113,6 +113,11 @@ public class SAXParser * grammar pool. */ public SAXParser(SymbolTable symbolTable, XMLGrammarPool grammarPool) { + this(symbolTable, grammarPool, null, null); + } + + public SAXParser(SymbolTable symbolTable, XMLGrammarPool grammarPool, + XMLSecurityPropertyManager securityPropertyMgr, XMLSecurityManager securityManager) { super(new XIncludeAwareParserConfiguration()); // set features @@ -128,7 +133,7 @@ public class SAXParser fConfiguration.setProperty(XMLGRAMMAR_POOL, grammarPool); } - initSecurityManager(); + initSecurityManager(securityPropertyMgr, securityManager); } // (SymbolTable,XMLGrammarPool) /** @@ -172,25 +177,4 @@ public class SAXParser } } } - - /** - * Initiates the SecurityManager. This becomes necessary when the SAXParser - * is constructed directly by, for example, XMLReaderFactory rather than - * through SAXParserFactory. - */ - private void initSecurityManager() { - try { - if (securityManager == null) { - securityManager = new XMLSecurityManager(true); - super.setProperty(Constants.SECURITY_MANAGER, securityManager); - } - - if (securityPropertyManager == null) { - securityPropertyManager = new XMLSecurityPropertyManager(); - super.setProperty(JdkConstants.XML_SECURITY_PROPERTY_MANAGER, securityPropertyManager); - } - } catch (SAXException e) { - Utils.dPrint(() -> e.getMessage()); - } - } } // class SAXParser diff --git a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/parsers/XIncludeAwareParserConfiguration.java b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/parsers/XIncludeAwareParserConfiguration.java index 07a5498a712..cbe555adcd1 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/parsers/XIncludeAwareParserConfiguration.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/parsers/XIncludeAwareParserConfiguration.java @@ -1,6 +1,5 @@ /* - * reserved comment block - * DO NOT REMOVE OR ALTER! + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -25,6 +24,7 @@ import com.sun.org.apache.xerces.internal.impl.Constants; import com.sun.org.apache.xerces.internal.util.FeatureState; import com.sun.org.apache.xerces.internal.util.NamespaceSupport; import com.sun.org.apache.xerces.internal.util.SymbolTable; +import com.sun.org.apache.xerces.internal.utils.XMLSecurityPropertyManager; import com.sun.org.apache.xerces.internal.xinclude.XIncludeHandler; import com.sun.org.apache.xerces.internal.xinclude.XIncludeNamespaceSupport; import com.sun.org.apache.xerces.internal.xni.NamespaceContext; @@ -33,6 +33,7 @@ import com.sun.org.apache.xerces.internal.xni.grammars.XMLGrammarPool; import com.sun.org.apache.xerces.internal.xni.parser.XMLComponentManager; import com.sun.org.apache.xerces.internal.xni.parser.XMLConfigurationException; import com.sun.org.apache.xerces.internal.xni.parser.XMLDocumentSource; +import jdk.xml.internal.XMLSecurityManager; /** * This class is the configuration used to parse XML 1.0 and XML 1.1 documents @@ -40,6 +41,7 @@ import com.sun.org.apache.xerces.internal.xni.parser.XMLDocumentSource; * * @author Michael Glavassevich, IBM * + * @LastModified: Nov 2023 */ public class XIncludeAwareParserConfiguration extends XML11Configuration { @@ -88,7 +90,7 @@ public class XIncludeAwareParserConfiguration extends XML11Configuration { /** Default constructor. */ public XIncludeAwareParserConfiguration() { - this(null, null, null); + this(null, null, null, null, null); } // () /** @@ -97,7 +99,7 @@ public class XIncludeAwareParserConfiguration extends XML11Configuration { * @param symbolTable The symbol table to use. */ public XIncludeAwareParserConfiguration(SymbolTable symbolTable) { - this(symbolTable, null, null); + this(symbolTable, null, null, null, null); } // (SymbolTable) /** @@ -111,7 +113,7 @@ public class XIncludeAwareParserConfiguration extends XML11Configuration { public XIncludeAwareParserConfiguration( SymbolTable symbolTable, XMLGrammarPool grammarPool) { - this(symbolTable, grammarPool, null); + this(symbolTable, grammarPool, null, null, null); } // (SymbolTable,XMLGrammarPool) /** @@ -123,11 +125,15 @@ public class XIncludeAwareParserConfiguration extends XML11Configuration { * @param grammarPool The grammar pool to use. * @param parentSettings The parent settings. */ - public XIncludeAwareParserConfiguration( - SymbolTable symbolTable, - XMLGrammarPool grammarPool, + public XIncludeAwareParserConfiguration(SymbolTable symbolTable, XMLGrammarPool grammarPool, XMLComponentManager parentSettings) { - super(symbolTable, grammarPool, parentSettings); + this(symbolTable, grammarPool, parentSettings, null, null); + } + + public XIncludeAwareParserConfiguration(SymbolTable symbolTable, XMLGrammarPool grammarPool, + XMLComponentManager parentSettings, XMLSecurityPropertyManager securityPropertyMgr, + XMLSecurityManager securityManager) { + super(symbolTable, grammarPool, parentSettings, securityPropertyMgr, securityManager); final String[] recognizedFeatures = { ALLOW_UE_AND_NOTATION_EVENTS, diff --git a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/parsers/XML11Configuration.java b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/parsers/XML11Configuration.java index b85e0f319d0..d4db3be16cf 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/parsers/XML11Configuration.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/parsers/XML11Configuration.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2023, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -46,6 +46,7 @@ import com.sun.org.apache.xerces.internal.util.FeatureState; import com.sun.org.apache.xerces.internal.util.ParserConfigurationSettings; import com.sun.org.apache.xerces.internal.util.PropertyState; import com.sun.org.apache.xerces.internal.util.SymbolTable; +import com.sun.org.apache.xerces.internal.utils.XMLSecurityPropertyManager; import com.sun.org.apache.xerces.internal.xni.XMLDTDContentModelHandler; import com.sun.org.apache.xerces.internal.xni.XMLDTDHandler; import com.sun.org.apache.xerces.internal.xni.XMLDocumentHandler; @@ -70,6 +71,7 @@ import javax.xml.XMLConstants; import javax.xml.catalog.CatalogFeatures; import jdk.xml.internal.JdkConstants; import jdk.xml.internal.JdkXmlUtils; +import jdk.xml.internal.XMLSecurityManager; /** * This class is the configuration used to parse XML 1.0 and XML 1.1 documents. @@ -78,7 +80,7 @@ import jdk.xml.internal.JdkXmlUtils; * @author Neil Graham, IBM * @author Michael Glavassevich, IBM * - * @LastModified: May 2021 + * @LastModified: Nov 2023 */ public class XML11Configuration extends ParserConfigurationSettings implements XMLPullParserConfiguration, XML11Configurable { @@ -432,7 +434,7 @@ public class XML11Configuration extends ParserConfigurationSettings /** Default constructor. */ public XML11Configuration() { - this(null, null, null); + this(null, null, null, null, null); } // () /** @@ -441,7 +443,7 @@ public class XML11Configuration extends ParserConfigurationSettings * @param symbolTable The symbol table to use. */ public XML11Configuration(SymbolTable symbolTable) { - this(symbolTable, null, null); + this(symbolTable, null, null, null, null); } // (SymbolTable) /** @@ -456,7 +458,7 @@ public class XML11Configuration extends ParserConfigurationSettings * @param grammarPool The grammar pool to use. */ public XML11Configuration(SymbolTable symbolTable, XMLGrammarPool grammarPool) { - this(symbolTable, grammarPool, null); + this(symbolTable, grammarPool, null, null, null); } // (SymbolTable,XMLGrammarPool) /** @@ -471,10 +473,14 @@ public class XML11Configuration extends ParserConfigurationSettings * @param grammarPool The grammar pool to use. * @param parentSettings The parent settings. */ - public XML11Configuration( - SymbolTable symbolTable, - XMLGrammarPool grammarPool, - XMLComponentManager parentSettings) { + public XML11Configuration(SymbolTable symbolTable, XMLGrammarPool grammarPool, + XMLComponentManager parentSettings) { + this(symbolTable, grammarPool, parentSettings, null, null); + } + + public XML11Configuration(SymbolTable symbolTable, XMLGrammarPool grammarPool, + XMLComponentManager parentSettings, XMLSecurityPropertyManager securityPropertyMgr, + XMLSecurityManager securityManager) { super(parentSettings); @@ -592,7 +598,7 @@ public class XML11Configuration extends ParserConfigurationSettings fProperties.put(XMLGRAMMAR_POOL, fGrammarPool); } - fEntityManager = new XMLEntityManager(); + fEntityManager = new XMLEntityManager(securityPropertyMgr, securityManager); fProperties.put(ENTITY_MANAGER, fEntityManager); addCommonComponent(fEntityManager); @@ -640,11 +646,6 @@ public class XML11Configuration extends ParserConfigurationSettings // REVISIT: What is the right thing to do? -Ac } - // Initialize Catalog features - for( CatalogFeatures.Feature f : CatalogFeatures.Feature.values()) { - fProperties.put(f.getPropertyName(), null); - } - setProperty(JdkConstants.CDATA_CHUNK_SIZE, JdkConstants.CDATA_CHUNK_SIZE_DEFAULT); fConfigUpdated = false; diff --git a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/parsers/XMLParser.java b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/parsers/XMLParser.java index 0bd3dab5678..01d1c904b5e 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/parsers/XMLParser.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/parsers/XMLParser.java @@ -28,7 +28,9 @@ import com.sun.org.apache.xerces.internal.xni.XNIException; import com.sun.org.apache.xerces.internal.xni.parser.XMLInputSource; import com.sun.org.apache.xerces.internal.xni.parser.XMLParserConfiguration; import jdk.xml.internal.JdkConstants; +import jdk.xml.internal.Utils; import jdk.xml.internal.XMLSecurityManager; +import org.xml.sax.SAXException; import org.xml.sax.SAXNotSupportedException; import org.xml.sax.SAXNotRecognizedException; @@ -48,7 +50,7 @@ import org.xml.sax.SAXNotRecognizedException; * * @author Arnaud Le Hors, IBM * @author Andy Clark, IBM - * @LastModified: July 2023 + * @LastModified: Nov 2023 */ public abstract class XMLParser { @@ -127,20 +129,29 @@ public abstract class XMLParser { public void parse(XMLInputSource inputSource) throws XNIException, IOException { // null indicates that the parser is called directly, initialize them - if (securityManager == null) { - securityManager = new XMLSecurityManager(true); - fConfiguration.setProperty(Constants.SECURITY_MANAGER, securityManager); - } - if (securityPropertyManager == null) { - securityPropertyManager = new XMLSecurityPropertyManager(); - fConfiguration.setProperty(JdkConstants.XML_SECURITY_PROPERTY_MANAGER, securityPropertyManager); - } - + initSecurityManager(null, null); reset(); fConfiguration.parse(inputSource); } // parse(XMLInputSource) + /** + * Initiates the SecurityManager. This becomes necessary when the Parser + * is constructed directly by, for example, XMLReaderFactory rather than + * through SAXParserFactory. + */ + void initSecurityManager(XMLSecurityPropertyManager spm, XMLSecurityManager sm) { + if (securityManager == null) { + securityManager = sm != null ? sm : new XMLSecurityManager(true); + } + fConfiguration.setProperty(Constants.SECURITY_MANAGER, securityManager); + + if (securityPropertyManager == null) { + securityPropertyManager = spm != null ? spm : new XMLSecurityPropertyManager(); + } + fConfiguration.setProperty(JdkConstants.XML_SECURITY_PROPERTY_MANAGER, securityPropertyManager); + } + // // Protected methods // diff --git a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/util/ParserConfigurationSettings.java b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/util/ParserConfigurationSettings.java index 377bb108750..caa4ade1df8 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/util/ParserConfigurationSettings.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/util/ParserConfigurationSettings.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2023, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -28,6 +28,7 @@ import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; +import jdk.xml.internal.JdkXmlUtils; /** * This class implements the basic operations for managing parser @@ -42,7 +43,7 @@ import java.util.Map; * * @author Andy Clark, IBM * - * @LastModified: Apr 2019 + * @LastModified: Nov 2023 */ public class ParserConfigurationSettings implements XMLComponentManager { @@ -97,6 +98,8 @@ public class ParserConfigurationSettings // save parent fParentSettings = parent; + // Initialize Catalog features + JdkXmlUtils.initCatalogFeatures(fProperties); } // (XMLComponentManager) // diff --git a/src/java.xml/share/classes/javax/xml/catalog/Util.java b/src/java.xml/share/classes/javax/xml/catalog/Util.java index 3bf6e31f98b..496626d64fa 100644 --- a/src/java.xml/share/classes/javax/xml/catalog/Util.java +++ b/src/java.xml/share/classes/javax/xml/catalog/Util.java @@ -165,7 +165,7 @@ class Util { case SCHEME_FILE: String path = uri.getPath(); File f1 = new File(path); - if (f1.isFile()) { + if (SecuritySupport.isFile(f1)) { return true; } break; diff --git a/src/java.xml/share/classes/jdk/xml/internal/JdkCatalog.java b/src/java.xml/share/classes/jdk/xml/internal/JdkCatalog.java new file mode 100644 index 00000000000..51890307399 --- /dev/null +++ b/src/java.xml/share/classes/jdk/xml/internal/JdkCatalog.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2023, 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 + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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 jdk.xml.internal; + +import java.net.URI; +import javax.xml.catalog.Catalog; +import javax.xml.catalog.CatalogFeatures; +import javax.xml.catalog.CatalogManager; + +/** + * Represents the built-in Catalog that hosts the DTDs for the Java platform. + */ +public class JdkCatalog { + public static final String JDKCATALOG = "/jdk/xml/internal/jdkcatalog/JDKCatalog.xml"; + private static final String JDKCATALOG_URL = SecuritySupport.getResource(JDKCATALOG).toExternalForm(); + public static Catalog catalog; + + public static void init(String resolve) { + if (catalog == null) { + CatalogFeatures cf = JdkXmlUtils.getCatalogFeatures(null, JDKCATALOG_URL, null, resolve); + catalog = CatalogManager.catalog(cf, URI.create(JDKCATALOG_URL)); + } + } +} diff --git a/src/java.xml/share/classes/jdk/xml/internal/JdkConstants.java b/src/java.xml/share/classes/jdk/xml/internal/JdkConstants.java index da373c3813f..26f163878ea 100644 --- a/src/java.xml/share/classes/jdk/xml/internal/JdkConstants.java +++ b/src/java.xml/share/classes/jdk/xml/internal/JdkConstants.java @@ -291,6 +291,7 @@ public final class JdkConstants { /** * System Property for the DTD property + * @since 22 */ public static final String DTD_PROPNAME = "jdk.xml.dtd.support"; @@ -299,6 +300,17 @@ public final class JdkConstants { public static final int IGNORE = 1; public static final int DENY = 2; + /** + * System Property for the JDKCatalog' RESOLVE property + * @since 22 + */ + public static final String JDKCATALOG_RESOLVE = "jdk.xml.jdkCatalog.resolve"; + + // Catalog Resolve Integer mappings for String values + public static final int CONTINUE = 0; + //public static final int IGNORE = 1; // same as that of DTD + public static final int STRICT = 2; + /** * Values for a feature */ 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 5acfdf6cbe8..7ee98622317 100644 --- a/src/java.xml/share/classes/jdk/xml/internal/JdkXmlUtils.java +++ b/src/java.xml/share/classes/jdk/xml/internal/JdkXmlUtils.java @@ -31,6 +31,7 @@ import com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl; import com.sun.org.apache.xerces.internal.util.ParserConfigurationSettings; import com.sun.org.apache.xerces.internal.xni.parser.XMLComponentManager; import com.sun.org.apache.xerces.internal.xni.parser.XMLConfigurationException; +import java.util.Map; import javax.xml.XMLConstants; import javax.xml.catalog.CatalogFeatures; import javax.xml.catalog.CatalogFeatures.Feature; @@ -156,6 +157,31 @@ public class JdkXmlUtils { return null; } + /** + * Initialize catalog features, including setting the default values and reading + * from the JAXP configuration file and System Properties. + * + * @param properties the Map object that holds the properties + */ + public static void initCatalogFeatures(Map properties) { + CatalogFeatures cf = getCatalogFeatures(); + for( CatalogFeatures.Feature f : CatalogFeatures.Feature.values()) { + properties.put(f.getPropertyName(), cf.get(f)); + } + } + + /** + * Creates an instance of a CatalogFeatures with default settings. + * Note: the CatalogFeatures is initialized with settings in the following + * order: + * Default values -> values in the config -> values set with System Properties + * + * @return an instance of a CatalogFeatures + */ + public static CatalogFeatures getCatalogFeatures() { + return CatalogFeatures.builder().build(); + } + /** * Creates an instance of a CatalogFeatures. * diff --git a/src/java.xml/share/classes/jdk/xml/internal/SecuritySupport.java b/src/java.xml/share/classes/jdk/xml/internal/SecuritySupport.java index 0a4f10cea4f..cfb2a264f7b 100644 --- a/src/java.xml/share/classes/jdk/xml/internal/SecuritySupport.java +++ b/src/java.xml/share/classes/jdk/xml/internal/SecuritySupport.java @@ -30,6 +30,7 @@ import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.net.URL; +import java.net.URLConnection; import java.nio.file.Paths; import java.security.AccessController; import java.security.CodeSource; @@ -266,6 +267,18 @@ public class SecuritySupport { -> f.exists())); } + /** + * Tests whether the input is file. + * + * @param f the file to be tested + * @return true if the input is file, false otherwise + */ + @SuppressWarnings("removal") + public static boolean isFile(final File f) { + return (AccessController.doPrivileged((PrivilegedAction) () + -> f.isFile())); + } + /** * Creates and returns a new FileInputStream from a file. * @param file the specified file @@ -283,6 +296,23 @@ public class SecuritySupport { } } + /** + * Returns an InputStream from a URLConnection. + * @param uc the URLConnection + * @return the InputStream + * @throws IOException if an I/O error occurs while creating the input stream + */ + @SuppressWarnings("removal") + public static InputStream getInputStream(final URLConnection uc) + throws IOException { + try { + return AccessController.doPrivileged((PrivilegedExceptionAction) () + -> uc.getInputStream()); + } catch (PrivilegedActionException e) { + throw (IOException) e.getException(); + } + } + /** * Returns the resource as a stream. * @param name the resource name @@ -294,6 +324,17 @@ public class SecuritySupport { SecuritySupport.class.getResourceAsStream("/"+name)); } + /** + * Returns the resource by the name. + * @param name the resource name + * @return the resource + */ + @SuppressWarnings("removal") + public static URL getResource(final String name) { + return AccessController.doPrivileged((PrivilegedAction) () -> + SecuritySupport.class.getResource(name)); + } + /** * Gets a resource bundle using the specified base name, the default locale, and the caller's class loader. * @param bundle the base name of the resource bundle, a fully qualified class name 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 07493c1b325..d343b99cf14 100644 --- a/src/java.xml/share/classes/jdk/xml/internal/XMLSecurityManager.java +++ b/src/java.xml/share/classes/jdk/xml/internal/XMLSecurityManager.java @@ -32,6 +32,9 @@ import java.util.Map; import java.util.Objects; import java.util.concurrent.CopyOnWriteArrayList; import java.util.stream.Collectors; +import javax.xml.catalog.CatalogManager; +import javax.xml.catalog.CatalogResolver; +import javax.xml.catalog.CatalogResolver.NotFoundAction; import javax.xml.stream.XMLInputFactory; import jdk.xml.internal.JdkProperty.State; import jdk.xml.internal.JdkProperty.ImplPropMap; @@ -67,15 +70,30 @@ public final class XMLSecurityManager { DTD_MAP = Collections.unmodifiableMap(map); } + // Valid values for Catalog Resolve, and mappings between the string and + // interger values + static final Map CR_MAP; + // Source Level JDK 8 + static { + Map map = new HashMap<>(); + map.put("continue", 0); + map.put("ignore", 1); + map.put("strict", 2); + CR_MAP = Collections.unmodifiableMap(map); + } + // Value converter for properties of type Boolean private static final BooleanMapper BOOLMAPPER = new BooleanMapper(); // Value converter for properties of type Integer private static final IntegerMapper INTMAPPER = new IntegerMapper(); - // DTD value map + // DTD value mapper private static final StringMapper DTDMAPPER = new StringMapper(DTD_MAP); + // Catalog Resolve value mapper + private static final StringMapper CRMAPPER = new StringMapper(CR_MAP); + /** * Limits managed by the security manager */ @@ -109,6 +127,8 @@ public final class XMLSecurityManager { JdkConstants.ALLOW, JdkConstants.ALLOW, Processor.PARSER, DTDMAPPER), XERCES_DISALLOW_DTD("disallowDTD", DISALLOW_DTD, null, null, 0, 0, Processor.PARSER, BOOLMAPPER), STAX_SUPPORT_DTD("supportDTD", XMLInputFactory.SUPPORT_DTD, null, null, 1, 1, Processor.PARSER, BOOLMAPPER), + JDKCATALOG_RESOLVE("JDKCatalogResolve", JdkConstants.JDKCATALOG_RESOLVE, JdkConstants.JDKCATALOG_RESOLVE, null, + JdkConstants.CONTINUE, JdkConstants.CONTINUE, Processor.PARSER, CRMAPPER), ; final String key; @@ -266,6 +286,48 @@ public final class XMLSecurityManager { //read system properties or the config file (jaxp.properties by default) readSystemProperties(); + // prepare the JDK Catalog + prepareCatalog(); + } + + /** + * Flag indicating whether the JDK Catalog has been initialized + */ + static volatile boolean jdkcatalogInitialized = false; + private final Object lock = new Object(); + + private void prepareCatalog() { + if (!jdkcatalogInitialized) { + synchronized (lock) { + if (!jdkcatalogInitialized) { + jdkcatalogInitialized = true; + String resolve = getLimitValueAsString(Limit.JDKCATALOG_RESOLVE); + JdkCatalog.init(resolve); + } + } + } + } + + /** + * Returns the JDKCatalogResolver with the current setting of the RESOLVE + * property. + * + * @return the JDKCatalogResolver + */ + public CatalogResolver getJDKCatalogResolver() { + String resolve = getLimitValueAsString(Limit.JDKCATALOG_RESOLVE); + return CatalogManager.catalogResolver(JdkCatalog.catalog, toActionType(resolve)); + } + + // convert the string value of the RESOLVE property to the corresponding + // action type + private NotFoundAction toActionType(String resolve) { + for (NotFoundAction type : NotFoundAction.values()) { + if (type.toString().equals(resolve)) { + return type; + } + } + return null; } /** diff --git a/src/java.xml/share/classes/jdk/xml/internal/jdkcatalog/JDKCatalog.xml b/src/java.xml/share/classes/jdk/xml/internal/jdkcatalog/JDKCatalog.xml new file mode 100644 index 00000000000..3919dd4981d --- /dev/null +++ b/src/java.xml/share/classes/jdk/xml/internal/jdkcatalog/JDKCatalog.xml @@ -0,0 +1,41 @@ + + + + + + + + + diff --git a/src/java.xml/share/classes/jdk/xml/internal/jdkcatalog/java/dtd/preferences.dtd b/src/java.xml/share/classes/jdk/xml/internal/jdkcatalog/java/dtd/preferences.dtd new file mode 100644 index 00000000000..27166e805c6 --- /dev/null +++ b/src/java.xml/share/classes/jdk/xml/internal/jdkcatalog/java/dtd/preferences.dtd @@ -0,0 +1,110 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/java.xml/share/classes/jdk/xml/internal/jdkcatalog/java/dtd/properties.dtd b/src/java.xml/share/classes/jdk/xml/internal/jdkcatalog/java/dtd/properties.dtd new file mode 100644 index 00000000000..4a22bd53d85 --- /dev/null +++ b/src/java.xml/share/classes/jdk/xml/internal/jdkcatalog/java/dtd/properties.dtd @@ -0,0 +1,15 @@ + + + + + + + + + + + + + diff --git a/src/java.xml/share/classes/module-info.java b/src/java.xml/share/classes/module-info.java index bb15ee81b51..0ed2ebfbe26 100644 --- a/src/java.xml/share/classes/module-info.java +++ b/src/java.xml/share/classes/module-info.java @@ -402,6 +402,11 @@ * @implNote * *
    + *
  • JDK built-in Catalog + * + *
  • *
  • Implementation Specific Properties * * + *

    JDK built-in Catalog

    + * The JDK has a built-in catalog that hosts the following DTDs defined by the Java Platform: + *
      + *
    • DTD for {@link java.util.prefs.Preferences java.util.prefs.Preferences}, preferences.dtd
    • + *
    • DTD for {@link java.util.Properties java.util.Properties}, properties.dtd
    • + *
    + *

    + * The catalog is loaded once when the first JAXP processor factory is created. + * + *

    External Resource Resolution Process with the built-in Catalog

    + * The JDK creates a {@link javax.xml.catalog.CatalogResolver CatalogResolver} + * with the built-in catalog when needed. This CatalogResolver is used as the + * default external resource resolver. + *

    + * XML processors may use resolvers (such as {@link org.xml.sax.EntityResolver EntityResolver}, + * {@link javax.xml.stream.XMLResolver XMLResolver}, and {@link javax.xml.catalog.CatalogResolver CatalogResolver}) + * to handle external references. In the absence of the user-defined resolvers, + * the JDK XML processors fall back to the default CatalogResolver to attempt to + * find a resolution before making a connection to fetch the resources. The fall-back + * also takes place if a user-defined resolver exists but allows the process to + * continue when unable to resolve the resource. + *

    + * If the default CatalogResolver is unable to locate a resource, it may signal + * the XML processors to continue processing, or skip the resource, or + * throw a CatalogException. The behavior is configured with the + * {@code jdk.xml.jdkcatalog.resolve} property. + * *

    Implementation Specific Properties

    * In addition to the standard JAXP Properties, * the JDK implementation supports a number of implementation specific properties @@ -752,7 +784,7 @@ * {@systemProperty jdk.xml.enableExtensionFunctions} * Determines if XSLT and XPath extension functions are to be allowed. * - * yes + * yes * Boolean * * true or false. True indicates that extension functions are allowed; False otherwise. @@ -842,6 +874,40 @@ * Method 1 * 22 * + * + * {@systemProperty jdk.xml.jdkcatalog.resolve} + * Instructs the JDK default CatalogResolver to act in accordance with the setting + * of this property when unable to resolve an external reference with the built-in Catalog. + * The options are: + *
      + *
    • + * {@code continue} -- Indicates that the processing should continue + *

    • + *
    • + * {@code ignore} -- Indicates that the reference is skipped + *

    • + *
    • + * {@code strict} -- Indicates that the resolver should throw a CatalogException + *

    • + *
    + * + * String + * + * {@code continue, ignore, and strict}. Values are case-insensitive. + * + * continue + * No + * Yes + * + * DOM
    + * SAX
    + * StAX
    + * Validation
    + * Transform + * + * Method 1 + * 22 + * * * *

    diff --git a/test/jaxp/javax/xml/jaxp/libs/jaxp/library/JAXPPolicyManager.java b/test/jaxp/javax/xml/jaxp/libs/jaxp/library/JAXPPolicyManager.java index 4d0598696f3..2940045352c 100644 --- a/test/jaxp/javax/xml/jaxp/libs/jaxp/library/JAXPPolicyManager.java +++ b/test/jaxp/javax/xml/jaxp/libs/jaxp/library/JAXPPolicyManager.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2023, 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 @@ -45,6 +45,7 @@ import java.util.StringJoiner; * This is a base class that every test class must extend if it needs to be run * with security mode. */ +@SuppressWarnings("removal") public class JAXPPolicyManager { /* * Backing up policy. @@ -161,6 +162,7 @@ public class JAXPPolicyManager { * Simple Policy class that supports the required Permissions to validate the * JAXP concrete classes. */ +@SuppressWarnings("removal") class TestPolicy extends Policy { private final static Set TEST_JARS = Set.of("jtreg.*jar", "javatest.*jar", "testng.*jar", "jcommander.*jar"); diff --git a/test/jaxp/javax/xml/jaxp/unittest/catalog/CatalogSupportBase.java b/test/jaxp/javax/xml/jaxp/unittest/catalog/CatalogSupportBase.java index 5ddacba953b..e22c1edf6c2 100644 --- a/test/jaxp/javax/xml/jaxp/unittest/catalog/CatalogSupportBase.java +++ b/test/jaxp/javax/xml/jaxp/unittest/catalog/CatalogSupportBase.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2023, 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 @@ -371,7 +371,9 @@ public class CatalogSupportBase { if (setUseCatalog) { factory.setFeature(XMLConstants.USE_CATALOG, useCatalog); } - factory.setProperty(CatalogFeatures.Feature.FILES.getPropertyName(), catalog); + if (catalog != null) { + factory.setProperty(CatalogFeatures.Feature.FILES.getPropertyName(), catalog); + } Schema schema = factory.newSchema(new StreamSource(new StringReader(xsd))); success("XMLSchema.dtd and datatypes.dtd are resolved."); @@ -472,7 +474,9 @@ public class CatalogSupportBase { } SAXParser parser = spf.newSAXParser(); - parser.setProperty(CatalogFeatures.Feature.FILES.getPropertyName(), catalog); + if (catalog != null) { + parser.setProperty(CatalogFeatures.Feature.FILES.getPropertyName(), catalog); + } return parser; } @@ -495,7 +499,9 @@ public class CatalogSupportBase { if (setUseCatalog) { reader.setFeature(XMLConstants.USE_CATALOG, useCatalog); } - reader.setProperty(CatalogFeatures.Feature.FILES.getPropertyName(), catalog); + if (catalog != null) { + reader.setProperty(CatalogFeatures.Feature.FILES.getPropertyName(), catalog); + } return reader; } @@ -566,7 +572,9 @@ public class CatalogSupportBase { if (setUseCatalog) { xif.setProperty(XMLConstants.USE_CATALOG, useCatalog); } - xif.setProperty(CatalogFeatures.Feature.FILES.getPropertyName(), catalog); + if (catalog != null) { + xif.setProperty(CatalogFeatures.Feature.FILES.getPropertyName(), catalog); + } ss = new StAXSource(xif.createXMLEventReader( xmlFileId, new FileInputStream(xmlFile))); } catch (Exception e) {} @@ -1013,6 +1021,7 @@ public class CatalogSupportBase { * Simple policy implementation that grants a set of permissions to all code * sources and protection domains. */ + @SuppressWarnings("removal") static class SimplePolicy extends Policy { private final Permissions perms; diff --git a/test/jaxp/javax/xml/jaxp/unittest/common/catalog/CatalogTestBase.java b/test/jaxp/javax/xml/jaxp/unittest/common/catalog/CatalogTestBase.java new file mode 100644 index 00000000000..17141fb474e --- /dev/null +++ b/test/jaxp/javax/xml/jaxp/unittest/common/catalog/CatalogTestBase.java @@ -0,0 +1,361 @@ +/* + * Copyright (c) 2023, 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.catalog; + +import common.util.TestBase; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.SAXParser; +import javax.xml.stream.XMLInputFactory; +import javax.xml.transform.TransformerFactory; +import javax.xml.validation.SchemaFactory; +//import org.testng.annotations.DataProvider; + +/** + * Tests the JDK Catalog + */ +public class CatalogTestBase extends TestBase { + /* + * DataProvider for testing configuring properties for parsers. + * + * Fields: + * file, FSP, state of setting, config file, system property, api property, + * Custom Catalog, error expected, error code or expected result + */ + //@DataProvider(name = "configWCatalogForParsers") + public Object[][] getConfigs(Processor processor) { + // file with an external DTD that's not in JdkCatalog + String fileDTDNotInC = "properties1.xml"; + // file with an external DTD that's in the Custom Catalog + String fileDTDInCC = "test.xml"; + // file with an external DTD that's in JdkCatalog + String javaDTD = "properties.xml"; + // file with an external DTD thats in the Custom Catalog + String w3cDTD = "xhtml11.xml"; + + // error code when CATALOG=strict; The cause for DOM + String errCode = "JAXP09040001"; + + // error (not from catalog) is expect when CATALOG=continue + boolean isErrExpected = true; + String expected1 = "invalid.site.com"; + + // expected when reference is resolved by Catalog + String expected3 = "", expected4 = ""; + switch (processor) { + case SAX: + errCode = "JAXP00090001"; + break; + case STAX: + errCode = "JAXP00090001"; + //errCode = "JAXP00090001"; + // StAX is non-validating parser + isErrExpected = false; + expected1 = ".*[\\w\\s]*(value1)[\\w\\s]*.*"; + expected3 = "Minimal XHTML 1.1 DocumentThis is a minimal XHTML 1.1 document."; + expected4 = ".*(123)[\\w\\s]*.*"; + break; + default: + break; + } + + return new Object[][]{ + // Case 1: external reference not in the JDKCatalog + /** + * Case 1-1: default setting; no Config file; Catalog: continue (by default) + * Expect: error as the parser continues and tries to access an invalid site + * java.net.UnknownHostException: invalid.site.com + */ + {fileDTDNotInC, null, null, null, null, null, null, isErrExpected, expected1}, + + /** + * Case 1-2: set JDK Catalog to strict in a Config file + * Expect: Exception since the external reference is not in the Catalog + * Error Msg: + * [Fatal Error] properties1.xml:2:75: JAXP00090001: The CatalogResolver is enabled with the catalog "JdkCatalog.xml", but a CatalogException is returned. + * org.xml.sax.SAXException: javax.xml.catalog.CatalogException: JAXP09040001: No match found for publicId 'null' and systemId 'http://invalid.site.com/dtd/properties1.dtd'. + * javax.xml.catalog.CatalogException: JAXP09040001: No match found for publicId 'null' and systemId 'http://invalid.site.com/dtd/properties1.dtd'. + */ + {fileDTDNotInC, null, PropertyState.CONFIG_FILE, Properties.CONFIG_FILE_CATALOG_STRICT, null, null, null, true, errCode}, + + /** + * Case 1-3: set CATALOG back to continue through the System Property + * Expect: error as the parser continues and tries to access an invalid site + * java.net.UnknownHostException: invalid.site.com + */ + {fileDTDNotInC, null, PropertyState.CONFIG_FILE_SYSTEM, Properties.CONFIG_FILE_CATALOG_STRICT, new Properties[]{Properties.CATALOG0}, null, null, isErrExpected, expected1}, + + /** + * Case 1-4: override the settings in Case 3 with the API property, and set Catalog to strict + * Expect: Exception since the external reference is not in the Catalog + */ + {fileDTDNotInC, null, PropertyState.CONFIG_FILE_SYSTEM_API, Properties.CONFIG_FILE_CATALOG_STRICT, new Properties[]{Properties.CATALOG0}, new Properties[]{Properties.CATALOG2}, null, true, errCode}, + + // Case 2: external reference in the JDKCatalog + /** + * Case 2-1: set CATALOG to strict in a Config file + * Compare to: case 1-2 + * Expect: pass without error + */ + {javaDTD, null, PropertyState.CONFIG_FILE, Properties.CONFIG_FILE_CATALOG_STRICT, null, null, null, false, expected1}, + + /** + * Case 2-2: override the settings in Case 3 with the API property, and set Catalog to strict + * Compare to: case 1-4 + * Expect: pass without error + */ + {javaDTD, null, PropertyState.CONFIG_FILE_SYSTEM_API, Properties.CONFIG_FILE_CATALOG_STRICT, new Properties[]{Properties.CATALOG0}, new Properties[]{Properties.CATALOG2}, null, false, expected1}, + + // Case 3: external reference in the Custom Catalog + /** + * Case 3-1: set CATALOG to strict in a Config file + * Compare to: case 1-2, would have resulted in an error without the + * custom catalog + * Expect: pass without error because the external reference is in + * the custom catalog + */ + {fileDTDInCC, null, PropertyState.CONFIG_FILE, Properties.CONFIG_FILE_CATALOG_STRICT, null, null, CustomCatalog.STRICT, false, expected4}, + + /** + * Case 3-2: override the settings in Case 3 with the API property, and set Catalog to strict + * Compare to: case 1-4, would have resulted in an error without the + * custom catalog + * Expect: pass without error + */ + {fileDTDInCC, null, PropertyState.CONFIG_FILE_SYSTEM_API, Properties.CONFIG_FILE_CATALOG_STRICT, new Properties[]{Properties.CATALOG0}, new Properties[]{Properties.CATALOG2}, CustomCatalog.STRICT, false, expected4}, + + // Case 4: Parameter Entity reference + /** + * Case 4-1: set CATALOG to strict in a Config file + * Compare to: case 1-2, would have resulted in an error since the external + * reference can not be found + * Expect: pass without error because the external reference is in + * the custom catalog + */ + {"testExternalParameter.xml", null, PropertyState.CONFIG_FILE, Properties.CONFIG_FILE_CATALOG_STRICT, null, null, CustomCatalog.STRICT, false, expected1}, + + // Case 5: resolve xInclude with the Custom Catalog + /** + * Case 5-1: set CATALOG to strict in a Config file + * Compare to: case 1-2, would have resulted in an error without the + * custom catalog + * Expect: pass without error because the external reference is in + * the custom catalog + */ + {"XI_roottest.xml", null, PropertyState.CONFIG_FILE, Properties.CONFIG_FILE_CATALOG_STRICT, null, null, CustomCatalog.STRICT, false, ""}, + + }; + } + + /* + * DataProvider for testing configuring properties for validation or transform. + * + * Fields: + * xml file, xsd or xsl file, FSP, state of setting, config file, system property, + * api property, Custom Catalog, error expected, error code or expected result + */ + //@DataProvider(name = "validationOrTransform") + public Object[][] getConfig(String m) { + // Schema Import + String xmlFile = "XSDImport_company.xsd"; + String xsdOrXsl = null; + String expected = ""; + String errCode = "JAXP00090001"; + + switch (m) { + case "SchemaTest2": + // Schema Include + xmlFile = "XSDInclude_company.xsd"; + break; + case "Validation": + // Schema Location + xmlFile = "val_test.xml"; + break; + case "Stylesheet": + errCode = "JAXP09040001"; + xmlFile = "XSLDTD.xsl"; + break; + case "Transform": + xmlFile = "XSLPI.xml"; + errCode = "JAXP09040001"; + xsdOrXsl = "" + + "" + + "" + + "" + +"]>" + + "" + + "" + + " "; + break; + default: + break; + } + + return new Object[][]{ + // Case 1: external reference not in the JDKCatalog + /** + * Case 1-1: default setting; no Config file; Catalog: continue + * Expect: pass without error + */ + {xmlFile, xsdOrXsl, null, null, null, null, null, null, false, expected}, + + /** + * Case 1-2: set CATALOG to strict in a Config file + * Expect: Exception since the external reference is not in the Catalog + * Sample Error Msg: + * org.xml.sax.SAXParseException; systemId: file:path/XSDImport_company.xsd; + * lineNumber: 10; columnNumber: 11; + * JAXP00090001: The CatalogResolver is enabled with the catalog "JdkCatalog.xml", + * but a CatalogException is returned. + */ + {xmlFile, xsdOrXsl, null, PropertyState.CONFIG_FILE, Properties.CONFIG_FILE_CATALOG_STRICT, null, null, null, true, errCode}, + + /** + * Case 1-3: set CATALOG back to continue through the System Property + * Expect: pass without error + */ + {xmlFile, xsdOrXsl, null, PropertyState.CONFIG_FILE_SYSTEM, Properties.CONFIG_FILE_CATALOG_STRICT, new Properties[]{Properties.CATALOG0}, null, null, false, expected}, + + /** + * Case 1-4: override the settings in Case 3 with the API property, and set Catalog to strict + * Expect: Exception since the external reference is not in the Catalog + */ + {xmlFile, xsdOrXsl, null, PropertyState.CONFIG_FILE_SYSTEM_API, Properties.CONFIG_FILE_CATALOG_STRICT, new Properties[]{Properties.CATALOG0}, new Properties[]{Properties.CATALOG2}, null, true, errCode}, + + /** + * Case 1-5: use Custom Catalog to resolve external references + * Expect: pass without error + */ + {xmlFile, xsdOrXsl, null, PropertyState.CONFIG_FILE_SYSTEM_API, Properties.CONFIG_FILE_CATALOG_STRICT, new Properties[]{Properties.CATALOG0}, new Properties[]{Properties.CATALOG2}, CustomCatalog.STRICT, false, expected}, + + }; + } + +// @Test(dataProvider = "configWCatalogForParsers", priority=0) + public void testDOM(String filename, Properties fsp, PropertyState state, + Properties config, Properties[] sysProp, Properties[] apiProp, CustomCatalog cc, + boolean expectError, String error) throws Exception { + + DocumentBuilderFactory dbf = getDBF(fsp, state, config, sysProp, apiProp, cc); + process(filename, dbf, expectError, error); + } + +// @Test(dataProvider = "configWCatalogForParsers") + public void testSAX(String filename, Properties fsp, PropertyState state, + Properties config, Properties[] sysProp, Properties[] apiProp, CustomCatalog cc, + boolean expectError, String error) throws Exception { + + SAXParser parser = getSAXParser(fsp, state, config, sysProp, apiProp, cc); + process(filename, parser, expectError, error); + } + +// @Test(dataProvider = "configWCatalogForParsers") + public void testStAX(String filename, Properties fsp, PropertyState state, + Properties config, Properties[] sysProp, Properties[] apiProp, CustomCatalog cc, + boolean expectError, String error) throws Exception { + + XMLInputFactory xif = getXMLInputFactory(state, config, sysProp, apiProp, cc); + process(filename, xif, expectError, error); + } + +// @Test(dataProvider = "validationOrTransform") + public void testSchema1(String filename, String xsd, Properties fsp, PropertyState state, + Properties config, Properties[] sysProp, Properties[] apiProp, CustomCatalog cc, + boolean expectError, String error) throws Exception { + + SchemaFactory sf = getSchemaFactory(fsp, state, config, sysProp, apiProp, cc); + process(filename, sf, expectError, error); + } + +// @Test(dataProvider = "validationOrTransform") + public void testSchema2(String filename, String xsd, Properties fsp, PropertyState state, + Properties config, Properties[] sysProp, Properties[] apiProp, CustomCatalog cc, + boolean expectError, String error) throws Exception { + testSchema1(filename, xsd, fsp, state, config, sysProp, apiProp, cc, expectError, error); + } + +// @Test(dataProvider = "validationOrTransform") + public void testValidation(String filename, String xsd, Properties fsp, PropertyState state, + Properties config, Properties[] sysProp, Properties[] apiProp, CustomCatalog cc, + boolean expectError, String error) throws Exception { + + SchemaFactory sf = getSchemaFactory(fsp, state, config, sysProp, apiProp, cc); + validate(filename, sf, expectError, error); + } + +// @Test(dataProvider = "validationOrTransform") + public void testStylesheet(String filename, String xsl, Properties fsp, PropertyState state, + Properties config, Properties[] sysProp, Properties[] apiProp, CustomCatalog cc, + boolean expectError, String error) throws Exception { + + TransformerFactory tf = getTransformerFactory(fsp, state, config, sysProp, apiProp, cc); + process(filename, tf, expectError, error); + } + +// @Test(dataProvider = "validationOrTransform") + public void testTransform(String filename, String xsl, Properties fsp, PropertyState state, + Properties config, Properties[] sysProp, Properties[] apiProp, CustomCatalog cc, + boolean expectError, String error) throws Exception { + + TransformerFactory tf = getTransformerFactory(fsp, state, config, sysProp, apiProp, cc); + transform(filename, xsl, tf, expectError, error); + } + + // parameters in the same order as the test method + String filename; String xsd; String xsl; Properties fsp; PropertyState state; + Properties config; Properties[] sysProp; Properties[] apiProp; CustomCatalog cc; + boolean expectError; String error; + + // Maps the DataProvider array to individual parameters + public void paramMap(Processor processor, String method, String index) { + int i = 0; + Object[][] params; + if (processor == Processor.VALIDATOR || + processor == Processor.TRANSFORMER) { + params = getConfig(method); + i = 1; + } else { + params = getConfigs(processor); + } + Object[] param = params[Integer.parseInt(index)]; + filename = (String)param[0]; + if (processor == Processor.VALIDATOR) { + xsd = (String)param[i]; + } else if (processor == Processor.TRANSFORMER) { + xsl = (String)param[i]; + } + fsp = (Properties)param[i + 1]; + state = (PropertyState)param[i + 2]; + config = (Properties)param[i + 3]; + sysProp = (Properties[])param[i + 4]; + apiProp = (Properties[])param[i + 5]; + cc = (CustomCatalog)param[i + 6]; + expectError = (boolean)param[i + 7]; + error = (String)param[i + 8]; + } +} diff --git a/test/jaxp/javax/xml/jaxp/unittest/common/catalog/DOMTest.java b/test/jaxp/javax/xml/jaxp/unittest/common/catalog/DOMTest.java new file mode 100644 index 00000000000..b5eeed48290 --- /dev/null +++ b/test/jaxp/javax/xml/jaxp/unittest/common/catalog/DOMTest.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2023, 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.catalog; + +/** + * @test @bug 8306055 + * @library /javax/xml/jaxp/libs /javax/xml/jaxp/unittest + * @modules java.xml/jdk.xml.internal + * @run driver common.catalog.DOMTest 0 // verifies default setting catalog.resolve=allow + * @run driver common.catalog.DOMTest 1 // verifies overriding with catalog.resolve=strict in a config file + * @run driver common.catalog.DOMTest 2 // verifies overriding with system property + * @run driver common.catalog.DOMTest 3 // verifies overriding with factory setting (catalog.resolve=strict) + * @run driver common.catalog.DOMTest 4 // verifies external DTD resolution with the JDK Catalog while resolve=strict in config file + * @run driver common.catalog.DOMTest 5 // verifies external DTD resolution with the JDK Catalog while resolve=strict in API setting + * @run driver common.catalog.DOMTest 6 // verifies external DTD resolution with a custom Catalog while resolve=strict in config file + * @run driver common.catalog.DOMTest 7 // verifies external DTD resolution with a custom Catalog while resolve=strict in API setting + * @run driver common.catalog.DOMTest 8 // verifies external parameter are resolved with a custom Catalog though resolve=strict in API setting + * @run driver common.catalog.DOMTest 9 // verifies XInclude are resolved with a custom Catalog though resolve=strict in API setting + * @summary verifies DOM's support of the JDK Catalog. + */ +public class DOMTest extends CatalogTestBase { + public static void main(String args[]) throws Exception { + new DOMTest().run(args[0]); + } + + public void run(String index) throws Exception { + paramMap(Processor.DOM, null, index); + super.testDOM(filename, fsp, state, config, sysProp, apiProp, cc, expectError, error); + + } +} diff --git a/test/jaxp/javax/xml/jaxp/unittest/common/catalog/SAXTest.java b/test/jaxp/javax/xml/jaxp/unittest/common/catalog/SAXTest.java new file mode 100644 index 00000000000..109568de287 --- /dev/null +++ b/test/jaxp/javax/xml/jaxp/unittest/common/catalog/SAXTest.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2023, 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.catalog; + +/** + * @test @bug 8306055 + * @library /javax/xml/jaxp/libs /javax/xml/jaxp/unittest + * @modules java.xml/jdk.xml.internal + * @run driver common.catalog.SAXTest 0 // verifies default setting catalog.resolve=allow + * @run driver common.catalog.SAXTest 1 // verifies overriding with catalog.resolve=strict in a config file + * @run driver common.catalog.SAXTest 2 // verifies overriding with system property + * @run driver common.catalog.SAXTest 3 // verifies overriding with factory setting (catalog.resolve=strict) + * @run driver common.catalog.SAXTest 4 // verifies external DTD resolution with the JDK Catalog while resolve=strict in config file + * @run driver common.catalog.SAXTest 5 // verifies external DTD resolution with the JDK Catalog while resolve=strict in API setting + * @run driver common.catalog.SAXTest 6 // verifies external DTD resolution with a custom Catalog while resolve=strict in config file + * @run driver common.catalog.SAXTest 7 // verifies external DTD resolution with a custom Catalog while resolve=strict in API setting + * @run driver common.catalog.SAXTest 8 // verifies external parameter are resolved with a custom Catalog though resolve=strict in API setting + * @run driver common.catalog.SAXTest 9 // verifies XInclude are resolved with a custom Catalog though resolve=strict in API setting + * @summary verifies DOM's support of the JDK Catalog. + + */ +public class SAXTest extends CatalogTestBase { + public static void main(String args[]) throws Exception { + new SAXTest().run(args[0]); + } + + public void run(String index) throws Exception { + paramMap(Processor.SAX, null, index); + super.testSAX(filename, fsp, state, config, sysProp, apiProp, cc, expectError, error); + } +} diff --git a/test/jaxp/javax/xml/jaxp/unittest/common/catalog/SchemaTest.java b/test/jaxp/javax/xml/jaxp/unittest/common/catalog/SchemaTest.java new file mode 100644 index 00000000000..698a5882d61 --- /dev/null +++ b/test/jaxp/javax/xml/jaxp/unittest/common/catalog/SchemaTest.java @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2023, 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.catalog; + +/** + * @test @bug 8306632 + * @library /javax/xml/jaxp/libs /javax/xml/jaxp/unittest + * @modules java.xml/jdk.xml.internal + * @run driver common.catalog.SchemaTest SchemaTest1 0 // verifies default setting dtd.support=allow + * @run driver common.catalog.SchemaTest SchemaTest1 1 // verifies overriding with config file + * @run driver common.catalog.SchemaTest SchemaTest1 2 // verifies overriding with system property + * @run driver common.catalog.SchemaTest SchemaTest1 3 // verifies overriding with factory setting (DTD=deny) + * @run driver common.catalog.SchemaTest SchemaTest1 4 // verifies DTD=ignore + * @run driver common.catalog.SchemaTest SchemaTest2 0 // verifies default setting dtd.support=allow + * @run driver common.catalog.SchemaTest SchemaTest2 1 // verifies overriding with config file + * @run driver common.catalog.SchemaTest SchemaTest2 2 // verifies overriding with system property + * @run driver common.catalog.SchemaTest SchemaTest2 3 // verifies overriding with factory setting (DTD=deny) + * @run driver common.catalog.SchemaTest SchemaTest2 4 // verifies DTD=ignore + * @run driver common.catalog.SchemaTest Validation 0 // verifies default setting dtd.support=allow + * @run driver common.catalog.SchemaTest Validation 1 // verifies overriding with config file + * @run driver common.catalog.SchemaTest Validation 2 // verifies overriding with system property + * @run driver common.catalog.SchemaTest Validation 3 // verifies overriding with factory setting (DTD=deny) + * @run driver common.catalog.SchemaTest Validation 4 // verifies DTD=ignore + * @summary verifies Schema and Validation's support of the property jdk.xml.dtd.support. + */ +public class SchemaTest extends CatalogTestBase { + + public static void main(String args[]) throws Exception { + new SchemaTest().run(args[0], args[1]); + } + + public void run(String method, String index) throws Exception { + paramMap(Processor.VALIDATOR, method, index); + switch (method) { + case "SchemaTest1": + super.testSchema1(filename, xsd, fsp, state, config, sysProp, apiProp, cc, expectError, error); + break; + case "SchemaTest2": + super.testSchema2(filename, xsd, fsp, state, config, sysProp, apiProp, cc, expectError, error); + break; + case "Validation": + super.testValidation(filename, xsd, fsp, state, config, sysProp, apiProp, cc, expectError, error); + break; + } + } +} diff --git a/test/jaxp/javax/xml/jaxp/unittest/common/catalog/StAXTest.java b/test/jaxp/javax/xml/jaxp/unittest/common/catalog/StAXTest.java new file mode 100644 index 00000000000..d5a530bac25 --- /dev/null +++ b/test/jaxp/javax/xml/jaxp/unittest/common/catalog/StAXTest.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2023, 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.catalog; + +/** + * @test @bug 8306055 + * @library /javax/xml/jaxp/libs /javax/xml/jaxp/unittest + * @modules java.xml/jdk.xml.internal + * @run driver common.catalog.StAXTest 0 // verifies default setting catalog.resolve=allow + * @run driver common.catalog.StAXTest 1 // verifies overriding with catalog.resolve=strict in a config file + * @run driver common.catalog.StAXTest 2 // verifies overriding with system property + * @run driver common.catalog.StAXTest 3 // verifies overriding with factory setting (catalog.resolve=strict) + * @run driver common.catalog.StAXTest 4 // verifies external DTD resolution with the JDK Catalog while resolve=strict in config file + * @run driver common.catalog.StAXTest 5 // verifies external DTD resolution with the JDK Catalog while resolve=strict in API setting + * @run driver common.catalog.StAXTest 6 // verifies external DTD resolution with a custom Catalog while resolve=strict in config file + * @run driver common.catalog.StAXTest 7 // verifies external DTD resolution with a custom Catalog while resolve=strict in API setting + * @run driver common.catalog.StAXTest 8 // verifies external parameter are resolved with a custom Catalog though resolve=strict in API setting + * @run driver common.catalog.StAXTest 9 // verifies XInclude are resolved with a custom Catalog though resolve=strict in API setting + * @summary verifies DOM's support of the JDK Catalog. + */ +public class StAXTest extends CatalogTestBase { + public static void main(String args[]) throws Exception { + new StAXTest().run(args[0]); + } + + public void run(String index) throws Exception { + paramMap(Processor.STAX, null, index); + super.testStAX(filename, fsp, state, config, sysProp, apiProp, cc, expectError, error); + + } +} diff --git a/test/jaxp/javax/xml/jaxp/unittest/common/catalog/TransformTest.java b/test/jaxp/javax/xml/jaxp/unittest/common/catalog/TransformTest.java new file mode 100644 index 00000000000..ff88a005448 --- /dev/null +++ b/test/jaxp/javax/xml/jaxp/unittest/common/catalog/TransformTest.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2023, 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.catalog; + +/** + * @test @bug 8306632 + * @library /javax/xml/jaxp/libs /javax/xml/jaxp/unittest + * @modules java.xml/jdk.xml.internal + * @run driver common.catalog.TransformTest Stylesheet 0 // verifies default setting dtd.support=allow + * @run driver common.catalog.TransformTest Stylesheet 1 // verifies overriding with config file + * @run driver common.catalog.TransformTest Stylesheet 2 // verifies overriding with system property + * @run driver common.catalog.TransformTest Stylesheet 3 // verifies overriding with factory setting (DTD=deny) + * @run driver common.catalog.TransformTest Stylesheet 4 // verifies DTD=ignore + * @run driver common.catalog.TransformTest Transform 0 // verifies default setting dtd.support=allow + * @run driver common.catalog.TransformTest Transform 1 // verifies overriding with config file + * @run driver common.catalog.TransformTest Transform 2 // verifies overriding with system property + * @run driver common.catalog.TransformTest Transform 3 // verifies overriding with factory setting (DTD=deny) + * @run driver common.catalog.TransformTest Transform 4 // verifies DTD=ignore + * @summary verifies Transform's support of the property jdk.xml.dtd.support. + */ +public class TransformTest extends CatalogTestBase { + + public static void main(String args[]) throws Exception { + new TransformTest().run(args[0], args[1]); + } + + public void run(String method, String index) throws Exception { + paramMap(Processor.TRANSFORMER, method, index); + switch (method) { + case "Stylesheet": + super.testStylesheet(filename, xsl, fsp, state, config, sysProp, apiProp, cc, expectError, error); + break; + case "Transform": + super.testTransform(filename, xsl, fsp, state, config, sysProp, apiProp, cc, expectError, error); + break; + } + } +} diff --git a/test/jaxp/javax/xml/jaxp/unittest/common/catalog/testcatalog/TestCatalog.xml b/test/jaxp/javax/xml/jaxp/unittest/common/catalog/testcatalog/TestCatalog.xml new file mode 100644 index 00000000000..216b3b81543 --- /dev/null +++ b/test/jaxp/javax/xml/jaxp/unittest/common/catalog/testcatalog/TestCatalog.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/jaxp/javax/xml/jaxp/unittest/common/catalog/testcatalog/dtds/XSLDTD.dtd b/test/jaxp/javax/xml/jaxp/unittest/common/catalog/testcatalog/dtds/XSLDTD.dtd new file mode 100644 index 00000000000..4317283e3d1 --- /dev/null +++ b/test/jaxp/javax/xml/jaxp/unittest/common/catalog/testcatalog/dtds/XSLDTD.dtd @@ -0,0 +1,108 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/jaxp/javax/xml/jaxp/unittest/common/catalog/testcatalog/dtds/paramEntity.dtd b/test/jaxp/javax/xml/jaxp/unittest/common/catalog/testcatalog/dtds/paramEntity.dtd new file mode 100644 index 00000000000..61768c96412 --- /dev/null +++ b/test/jaxp/javax/xml/jaxp/unittest/common/catalog/testcatalog/dtds/paramEntity.dtd @@ -0,0 +1,2 @@ + + diff --git a/test/jaxp/javax/xml/jaxp/unittest/common/catalog/testcatalog/dtds/test.dtd b/test/jaxp/javax/xml/jaxp/unittest/common/catalog/testcatalog/dtds/test.dtd new file mode 100644 index 00000000000..eb32c89a739 --- /dev/null +++ b/test/jaxp/javax/xml/jaxp/unittest/common/catalog/testcatalog/dtds/test.dtd @@ -0,0 +1,6 @@ + + + + + + diff --git a/test/jaxp/javax/xml/jaxp/unittest/common/catalog/testcatalog/xinclude/XI_red.dtd b/test/jaxp/javax/xml/jaxp/unittest/common/catalog/testcatalog/xinclude/XI_red.dtd new file mode 100644 index 00000000000..147fe93bde0 --- /dev/null +++ b/test/jaxp/javax/xml/jaxp/unittest/common/catalog/testcatalog/xinclude/XI_red.dtd @@ -0,0 +1,4 @@ + diff --git a/test/jaxp/javax/xml/jaxp/unittest/common/catalog/testcatalog/xinclude/XI_simple.xml b/test/jaxp/javax/xml/jaxp/unittest/common/catalog/testcatalog/xinclude/XI_simple.xml new file mode 100644 index 00000000000..da7b962b62c --- /dev/null +++ b/test/jaxp/javax/xml/jaxp/unittest/common/catalog/testcatalog/xinclude/XI_simple.xml @@ -0,0 +1,18 @@ + + + + + + + + text + + + + + + + + + + diff --git a/test/jaxp/javax/xml/jaxp/unittest/common/catalog/testcatalog/xinclude/XI_test2.xml b/test/jaxp/javax/xml/jaxp/unittest/common/catalog/testcatalog/xinclude/XI_test2.xml new file mode 100644 index 00000000000..96c173a833f --- /dev/null +++ b/test/jaxp/javax/xml/jaxp/unittest/common/catalog/testcatalog/xinclude/XI_test2.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/test/jaxp/javax/xml/jaxp/unittest/common/catalog/testcatalog/xinclude/XI_utf8.xml b/test/jaxp/javax/xml/jaxp/unittest/common/catalog/testcatalog/xinclude/XI_utf8.xml new file mode 100644 index 00000000000..8b591c92888 --- /dev/null +++ b/test/jaxp/javax/xml/jaxp/unittest/common/catalog/testcatalog/xinclude/XI_utf8.xml @@ -0,0 +1,4 @@ + + value1 trjsagdkasgdhasdgashgdhsadgashdg + + diff --git a/test/jaxp/javax/xml/jaxp/unittest/common/catalog/testcatalog/xsds/XSDImport_person.xsd b/test/jaxp/javax/xml/jaxp/unittest/common/catalog/testcatalog/xsds/XSDImport_person.xsd new file mode 100644 index 00000000000..ac5d718f5d3 --- /dev/null +++ b/test/jaxp/javax/xml/jaxp/unittest/common/catalog/testcatalog/xsds/XSDImport_person.xsd @@ -0,0 +1,12 @@ + + + + + + + + + \ No newline at end of file diff --git a/test/jaxp/javax/xml/jaxp/unittest/common/catalog/testcatalog/xsds/XSDImport_product.xsd b/test/jaxp/javax/xml/jaxp/unittest/common/catalog/testcatalog/xsds/XSDImport_product.xsd new file mode 100644 index 00000000000..73385552b42 --- /dev/null +++ b/test/jaxp/javax/xml/jaxp/unittest/common/catalog/testcatalog/xsds/XSDImport_product.xsd @@ -0,0 +1,11 @@ + + + + + + + + \ No newline at end of file diff --git a/test/jaxp/javax/xml/jaxp/unittest/common/catalog/testcatalog/xsds/XSDInclude_person.xsd b/test/jaxp/javax/xml/jaxp/unittest/common/catalog/testcatalog/xsds/XSDInclude_person.xsd new file mode 100644 index 00000000000..f4a5586bf77 --- /dev/null +++ b/test/jaxp/javax/xml/jaxp/unittest/common/catalog/testcatalog/xsds/XSDInclude_person.xsd @@ -0,0 +1,12 @@ + + + + + + + + + \ No newline at end of file diff --git a/test/jaxp/javax/xml/jaxp/unittest/common/catalog/testcatalog/xsds/XSDInclude_product.xsd b/test/jaxp/javax/xml/jaxp/unittest/common/catalog/testcatalog/xsds/XSDInclude_product.xsd new file mode 100644 index 00000000000..0c4ee7a2b92 --- /dev/null +++ b/test/jaxp/javax/xml/jaxp/unittest/common/catalog/testcatalog/xsds/XSDInclude_product.xsd @@ -0,0 +1,11 @@ + + + + + + + + \ No newline at end of file diff --git a/test/jaxp/javax/xml/jaxp/unittest/common/catalog/testcatalog/xsds/val_test.xsd b/test/jaxp/javax/xml/jaxp/unittest/common/catalog/testcatalog/xsds/val_test.xsd new file mode 100644 index 00000000000..562eb6b2291 --- /dev/null +++ b/test/jaxp/javax/xml/jaxp/unittest/common/catalog/testcatalog/xsds/val_test.xsd @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/jaxp/javax/xml/jaxp/unittest/common/config/files/catalog2.properties b/test/jaxp/javax/xml/jaxp/unittest/common/config/files/catalog2.properties new file mode 100644 index 00000000000..16cf13c1a96 --- /dev/null +++ b/test/jaxp/javax/xml/jaxp/unittest/common/config/files/catalog2.properties @@ -0,0 +1,36 @@ +################################################################################ +# XML Library (java.xml) Configuration File +# +# This file is in java.util.Properties format and typically located in the conf +# directory of the Java installation. It may contain key/value pairs for specifying +# the implementation class of a factory and/or properties that have corresponding +# system properties. +# +# This file can be replaced by specifying a filename with the java.xml.config.file +# system property. For example java -Djava.xml.config.file=myfile +################################################################################ + +# ---- Config File: for testing the CATALOG property ---- +# +# strict: report error if not resolved by the JDK Catalog +jdk.xml.jdkCatalog.resolve=strict +# Enable Extension Functions +jdk.xml.enableExtensionFunctions=true +# Disallow overriding the default parser +jdk.xml.overrideDefaultParser=false +# +# Implementation specific limits: +# +jdk.xml.entityExpansionLimit=64000 +jdk.xml.elementAttributeLimit=10000 +jdk.xml.maxOccurLimit=5000 +jdk.xml.totalEntitySizeLimit=100000 +jdk.xml.maxGeneralEntitySizeLimit=0 +jdk.xml.maxParameterEntitySizeLimit=1000000 +jdk.xml.entityReplacementLimit=300000 +jdk.xml.maxElementDepth=0 +jdk.xml.maxXMLNameLimit=1000 +jdk.xml.xpathExprGrpLimit=10 +jdk.xml.xpathExprOpLimit=100 +jdk.xml.xpathTotalOpLimit=10000 + diff --git a/test/jaxp/javax/xml/jaxp/unittest/common/config/files/jaxp.properties b/test/jaxp/javax/xml/jaxp/unittest/common/config/files/jaxp.properties index b43b5a3e8d1..7f1a48e7c1c 100644 --- a/test/jaxp/javax/xml/jaxp/unittest/common/config/files/jaxp.properties +++ b/test/jaxp/javax/xml/jaxp/unittest/common/config/files/jaxp.properties @@ -128,6 +128,11 @@ jdk.xml.overrideDefaultParser=false # # javax.xml.useCatalog=true # +# Implementation Specific Properties - DTD +# +# This property instructs the parsers to: deny, ignore or allow DTD processing. +# The following setting would cause the parser to reject DTD by throwing an exception. +# jdk.xml.dtd.support=deny # # Implementation Specific Properties - Limits # diff --git a/test/jaxp/javax/xml/jaxp/unittest/common/dtd/DTDTestBase.java b/test/jaxp/javax/xml/jaxp/unittest/common/dtd/DTDTestBase.java index f5985bd3615..b37b7da4e9a 100644 --- a/test/jaxp/javax/xml/jaxp/unittest/common/dtd/DTDTestBase.java +++ b/test/jaxp/javax/xml/jaxp/unittest/common/dtd/DTDTestBase.java @@ -17,15 +17,6 @@ import common.util.TestBase; * The DTD property controls how DTDs are processed. */ public class DTDTestBase extends TestBase { - static final String SRC_DIR; - static { - String srcDir = System.getProperty("test.src", "."); - if (IS_WINDOWS) { - srcDir = srcDir.replace('\\', '/'); - } - SRC_DIR = srcDir; - TEST_SOURCE_DIR = srcDir + "/../xmlfiles/"; - } public void testDOM(String filename, Properties fsp, PropertyState state, Properties config, Properties[] sysProp, Properties[] apiProp, diff --git a/test/jaxp/javax/xml/jaxp/unittest/common/util/TestBase.java b/test/jaxp/javax/xml/jaxp/unittest/common/util/TestBase.java index de0316aa79f..fa7d32fe4e4 100644 --- a/test/jaxp/javax/xml/jaxp/unittest/common/util/TestBase.java +++ b/test/jaxp/javax/xml/jaxp/unittest/common/util/TestBase.java @@ -67,13 +67,31 @@ public class TestBase { ORACLE_JAXP_PROPERTY_PREFIX + "getEntityCountInfo"; public static final String CATALOG_FILE = CatalogFeatures.Feature.FILES.getPropertyName(); public static final boolean IS_WINDOWS = System.getProperty("os.name").contains("Windows"); - public static String SRC_DIR = System.getProperty("test.src", "."); - public static String TEST_SOURCE_DIR; + public static String SRC_DIR; + public static String TEST_SOURCE_DIR, CONFIG_FILE_PATH, CATALOG_PATH; + static { + String srcDir = System.getProperty("test.src", "."); + if (IS_WINDOWS) { + srcDir = srcDir.replace('\\', '/'); + } + SRC_DIR = srcDir; + if (IS_WINDOWS) { + CATALOG_PATH = "file:///" + SRC_DIR + "/../catalog/testcatalog/TestCatalog.xml"; + } else { + CATALOG_PATH = "file://" + SRC_DIR + "/../catalog/testcatalog/TestCatalog.xml"; + } + TEST_SOURCE_DIR = srcDir + "/../xmlfiles/"; + CONFIG_FILE_PATH = SRC_DIR + "/../config/files/"; + } // configuration file system property private static final String CONFIG_FILE = "java.xml.config.file"; + // CATALOG Abbreviation: C + static final String C_FILE = CatalogFeatures.Feature.FILES.getPropertyName(); + static final String C_RESOLVE = CatalogFeatures.Feature.RESOLVE.getPropertyName(); + // Xerces Property public static final String DISALLOW_DTD = "http://apache.org/xml/features/disallow-doctype-decl"; public static final String LOAD_EXTERNAL_DTD = "http://apache.org/xml/features/nonvalidating/load-external-dtd"; @@ -84,6 +102,7 @@ public class TestBase { // Impl Specific Properties public static final String SP_DTD = "jdk.xml.dtd.support"; + public static final String SP_CATALOG = "jdk.xml.jdkCatalog.resolve"; public static final String OVERRIDE_PARSER = "jdk.xml.overrideDefaultParser"; // DTD/CATALOG constants @@ -97,7 +116,10 @@ public class TestBase { // JAXP Configuration File(JCF) location // DTD = deny - public static final String JCF_DTD2 = "../config/files/dtd2.properties"; + public static final String JCF_DTD2 = "dtd2.properties"; + + // CATALOG=strict + public static final String CONFIG_CATALOG_STRICT = "catalog2.properties"; String xmlExternalEntity, xmlExternalEntityId; @@ -107,7 +129,9 @@ public class TestBase { static enum SourceType { STREAM, SAX, STAX, DOM }; public static enum Properties { - CONFIG_FILE_DTD2(null, CONFIG_FILE, Type.FEATURE, getPath(JCF_DTD2)), + // config file: CATALOG = strict + CONFIG_FILE_CATALOG_STRICT(null, CONFIG_FILE, Type.FEATURE, getPath(CONFIG_FILE_PATH, CONFIG_CATALOG_STRICT)), + CONFIG_FILE_DTD2(null, CONFIG_FILE, Type.FEATURE, getPath(CONFIG_FILE_PATH, JCF_DTD2)), FSP(XMLConstants.FEATURE_SECURE_PROCESSING, null, Type.FEATURE, "true"), FSP_FALSE(XMLConstants.FEATURE_SECURE_PROCESSING, null, Type.FEATURE, "false"), @@ -115,6 +139,9 @@ public class TestBase { DTD0(SP_DTD, "ditto", Type.PROPERTY, DTD_ALLOW), DTD1(SP_DTD, "ditto", Type.PROPERTY, DTD_IGNORE), DTD2(SP_DTD, "ditto", Type.PROPERTY, DTD_DENY), + CATALOG0(SP_CATALOG, "ditto", Type.PROPERTY, RESOLVE_CONTINUE), + CATALOG1(SP_CATALOG, "ditto", Type.PROPERTY, RESOLVE_IGNORE), + CATALOG2(SP_CATALOG, "ditto", Type.PROPERTY, RESOLVE_STRICT), // StAX properties SUPPORT_DTD(XMLInputFactory.SUPPORT_DTD, null, Type.FEATURE, "true"), @@ -181,11 +208,34 @@ public class TestBase { CONFIG_FILE_SYSTEM_API, } + public static enum CustomCatalog { + // continue processing if no match found + CONTINUE(CATALOG_PATH, "continue"), + // skip if no match found + IGNORE(CATALOG_PATH, "ignore"), + // throws CatalogException if no match found + STRICT(CATALOG_PATH, "strict"); + + String file, resolve; + CustomCatalog(String file, String resolve) { + this.file = file; + this.resolve = resolve; + } + + public String file() { + return file; + } + + public String resolve() { + return resolve; + } + } + protected void process(String filename, DocumentBuilderFactory dbf, boolean expectError, String error) throws Exception { //dbf.setAttribute(CatalogFeatures.Feature.RESOLVE.getPropertyName(), "continue"); DocumentBuilder builder = dbf.newDocumentBuilder(); - File file = new File(getPath(filename)); + File file = new File(getPath(TEST_SOURCE_DIR, filename)); try { Document document = builder.parse(file); Assert.assertTrue(!expectError); @@ -198,7 +248,7 @@ public class TestBase { protected void process(String filename, SAXParser parser, boolean expectError, String error) throws Exception { - File file = new File(getPath(filename)); + File file = new File(getPath(TEST_SOURCE_DIR, filename)); try { parser.parse(file, new DefaultHandler()); Assert.assertTrue(!expectError); @@ -211,7 +261,7 @@ public class TestBase { protected void process(String filename, XMLInputFactory xif, boolean expectError, String expected) throws Exception { - String xml = getPath(filename); + String xml = getPath(TEST_SOURCE_DIR, filename); try { InputStream entityxml = new FileInputStream(xml); XMLStreamReader streamReader = xif.createXMLStreamReader(xml, entityxml); @@ -228,7 +278,7 @@ public class TestBase { protected void process(String filename, SchemaFactory sf, boolean expectError, String expected) throws Exception { - String xsd = getPath(filename); + String xsd = getPath(TEST_SOURCE_DIR, filename); try { Schema schema = sf.newSchema(new StreamSource(new File(xsd))); Assert.assertTrue(!expectError); @@ -240,7 +290,7 @@ public class TestBase { protected void process(String filename, TransformerFactory tf, boolean expectError, String expected) throws Exception { - String xsl = getPath(filename); + String xsl = getPath(TEST_SOURCE_DIR, filename); try { SAXSource xslSource = new SAXSource(new InputSource(xsl)); xslSource.setSystemId(xsl); @@ -254,7 +304,7 @@ public class TestBase { protected void transform(String xmlFile, String xsl, TransformerFactory tf, boolean expectError, String expected) throws Exception { - String xmlSysId = getPath(xmlFile); + String xmlSysId = getPath(TEST_SOURCE_DIR, xmlFile); try { SAXSource xslSource = new SAXSource(new InputSource(new StringReader(xsl))); //SAXSource xslSource = new SAXSource(new InputSource(xslSysId)); @@ -264,14 +314,13 @@ public class TestBase { transformer.transform(getSource(SourceType.STREAM, xmlSysId), new StreamResult(sw)); Assert.assertTrue(!expectError); } catch (Exception e) { - e.printStackTrace(); processError(expectError, expected, e); } } protected void validate(String filename, SchemaFactory sf, boolean expectError, String expected) throws Exception { - String xml = getPath(filename); + String xml = getPath(TEST_SOURCE_DIR, filename); try { Schema schema = sf.newSchema(); Validator validator = schema.newValidator(); @@ -309,6 +358,11 @@ public class TestBase { */ protected DocumentBuilderFactory getDBF(Properties fsp, PropertyState state, Properties config, Properties[] sysProp, Properties[] apiProp) { + return getDBF(fsp, state, config, sysProp, apiProp, null); + } + + protected DocumentBuilderFactory getDBF(Properties fsp, PropertyState state, + Properties config, Properties[] sysProp, Properties[] apiProp, CustomCatalog cc) { setSystemProperty(config, state, sysProp); DocumentBuilderFactory dbf = DocumentBuilderFactory.newDefaultNSInstance(); @@ -335,6 +389,10 @@ public class TestBase { } } } + if (cc != null) { + dbf.setAttribute(C_FILE, cc.file()); + dbf.setAttribute(C_RESOLVE, cc.resolve()); + } clearSystemProperty(state, sysProp); @@ -355,6 +413,11 @@ public class TestBase { */ public SAXParser getSAXParser(Properties fsp, PropertyState state, Properties config, Properties[] sysProp, Properties[] apiProp) throws Exception { + return getSAXParser(fsp, state, config, sysProp, apiProp, null); + } + + public SAXParser getSAXParser(Properties fsp, PropertyState state, Properties config, + Properties[] sysProp, Properties[] apiProp, CustomCatalog cc) throws Exception { setSystemProperty(config, state, sysProp); SAXParserFactory spf = SAXParserFactory.newDefaultNSInstance(); @@ -387,12 +450,22 @@ public class TestBase { } } + if (cc != null) { + parser.setProperty(C_FILE, cc.file()); + parser.setProperty(C_RESOLVE, cc.resolve()); + } + clearSystemProperty(state, sysProp); return parser; } protected XMLInputFactory getXMLInputFactory(PropertyState state, Properties config, Properties[] sysProp, Properties[] apiProp) { + return getXMLInputFactory(state, config, sysProp, apiProp, null); + } + + protected XMLInputFactory getXMLInputFactory(PropertyState state, + Properties config, Properties[] sysProp, Properties[] apiProp, CustomCatalog cc) { setSystemProperty(config, state, sysProp); XMLInputFactory factory = XMLInputFactory.newInstance(); @@ -402,6 +475,11 @@ public class TestBase { } } + if (cc != null) { + factory.setProperty(C_FILE, cc.file()); + factory.setProperty(C_RESOLVE, cc.resolve()); + } + clearSystemProperty(state, sysProp); return factory; @@ -410,6 +488,12 @@ public class TestBase { protected SchemaFactory getSchemaFactory(Properties fsp, PropertyState state, Properties config, Properties[] sysProp, Properties[] apiProp) throws Exception { + return getSchemaFactory(fsp, state, config, sysProp, apiProp, null); + } + + protected SchemaFactory getSchemaFactory(Properties fsp, PropertyState state, + Properties config, Properties[] sysProp, Properties[] apiProp, CustomCatalog cc) + throws Exception { setSystemProperty(config, state, sysProp); SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); @@ -427,6 +511,11 @@ public class TestBase { } } + if (cc != null) { + factory.setProperty(C_FILE, cc.file()); + factory.setProperty(C_RESOLVE, cc.resolve()); + } + clearSystemProperty(state, sysProp); return factory; @@ -435,6 +524,12 @@ public class TestBase { protected TransformerFactory getTransformerFactory(Properties fsp, PropertyState state, Properties config, Properties[] sysProp, Properties[] apiProp) throws Exception { + return getTransformerFactory(fsp, state, config, sysProp, apiProp, null); + } + + protected TransformerFactory getTransformerFactory(Properties fsp, PropertyState state, + Properties config, Properties[] sysProp, Properties[] apiProp, CustomCatalog cc) + throws Exception { setSystemProperty(config, state, sysProp); TransformerFactory tf = TransformerFactory.newInstance(); //tf.setAttribute(JDK_ENTITY_COUNT_INFO, "yes"); @@ -450,6 +545,10 @@ public class TestBase { } } } + if (cc != null) { + tf.setAttribute(C_FILE, cc.file()); + tf.setAttribute(C_RESOLVE, cc.resolve()); + } clearSystemProperty(state, sysProp); @@ -605,8 +704,8 @@ public class TestBase { } } - static String getPath(String file) { - String temp = TEST_SOURCE_DIR + file; + static String getPath(String base, String file) { + String temp = base + file; if (IS_WINDOWS) { temp = "/" + temp; } diff --git a/test/jaxp/javax/xml/jaxp/unittest/common/xmlfiles/XI_roottest.xml b/test/jaxp/javax/xml/jaxp/unittest/common/xmlfiles/XI_roottest.xml new file mode 100644 index 00000000000..bc6c2968f59 --- /dev/null +++ b/test/jaxp/javax/xml/jaxp/unittest/common/xmlfiles/XI_roottest.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/test/jaxp/javax/xml/jaxp/unittest/common/xmlfiles/test.xml b/test/jaxp/javax/xml/jaxp/unittest/common/xmlfiles/test.xml new file mode 100644 index 00000000000..991d823a2fe --- /dev/null +++ b/test/jaxp/javax/xml/jaxp/unittest/common/xmlfiles/test.xml @@ -0,0 +1,6 @@ + + + ]> +123&x1; diff --git a/test/jaxp/javax/xml/jaxp/unittest/common/xmlfiles/testExternalParameter.xml b/test/jaxp/javax/xml/jaxp/unittest/common/xmlfiles/testExternalParameter.xml new file mode 100644 index 00000000000..192d9ed633e --- /dev/null +++ b/test/jaxp/javax/xml/jaxp/unittest/common/xmlfiles/testExternalParameter.xml @@ -0,0 +1,12 @@ + + +%paraEntity; +]> + + value value1 + 10016 + + + +