8326915: NPE when a validating parser is restricted
Reviewed-by: lancea, naoto
This commit is contained in:
parent
f62f2adbc3
commit
a3d51d2027
@ -94,7 +94,7 @@ import org.xml.sax.InputSource;
|
|||||||
* @author K.Venugopal SUN Microsystems
|
* @author K.Venugopal SUN Microsystems
|
||||||
* @author Neeraj Bajaj SUN Microsystems
|
* @author Neeraj Bajaj SUN Microsystems
|
||||||
* @author Sunitha Reddy SUN Microsystems
|
* @author Sunitha Reddy SUN Microsystems
|
||||||
* @LastModified: Jan 2024
|
* @LastModified: Feb 2024
|
||||||
*/
|
*/
|
||||||
public class XMLEntityManager implements XMLComponent, XMLEntityResolver {
|
public class XMLEntityManager implements XMLComponent, XMLEntityResolver {
|
||||||
|
|
||||||
@ -1118,8 +1118,9 @@ public class XMLEntityManager implements XMLComponent, XMLEntityResolver {
|
|||||||
* this method attempts to resolve the resource as an EntityResolver first
|
* this method attempts to resolve the resource as an EntityResolver first
|
||||||
* and then URIResolver if no match is found.
|
* and then URIResolver if no match is found.
|
||||||
*/
|
*/
|
||||||
private XMLInputSource resolveEntityOrURI(CatalogResolver cr, String publicId, String systemId, String base) {
|
private XMLInputSource resolveEntityOrURI(String catalogName, CatalogResolver cr,
|
||||||
XMLInputSource xis = resolveEntity(cr, publicId, systemId, base);
|
String publicId, String systemId, String base) {
|
||||||
|
XMLInputSource xis = resolveEntity(catalogName, cr, publicId, systemId, base);
|
||||||
|
|
||||||
if (xis != null) {
|
if (xis != null) {
|
||||||
return xis;
|
return xis;
|
||||||
@ -1137,13 +1138,21 @@ public class XMLEntityManager implements XMLComponent, XMLEntityResolver {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private XMLInputSource resolveEntity(CatalogResolver cr, String publicId, String systemId, String base) {
|
private XMLInputSource resolveEntity(String catalogName, CatalogResolver cr,
|
||||||
|
String publicId, String systemId, String base) {
|
||||||
InputSource is = null;
|
InputSource is = null;
|
||||||
try {
|
try {
|
||||||
if (publicId != null || systemId != null) {
|
if (publicId != null || systemId != null) {
|
||||||
is = cr.resolveEntity(publicId, systemId);
|
is = cr.resolveEntity(publicId, systemId);
|
||||||
}
|
}
|
||||||
} catch (CatalogException e) {}
|
} catch (CatalogException e) {
|
||||||
|
//Note: XSDHandler does not set ErrorReporter on EntityManager
|
||||||
|
if (fErrorReporter != null) {
|
||||||
|
fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN,"CatalogException",
|
||||||
|
new Object[]{SecuritySupport.sanitizePath(catalogName)},
|
||||||
|
XMLErrorReporter.SEVERITY_FATAL_ERROR, e );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (is != null && !is.isEmpty()) {
|
if (is != null && !is.isEmpty()) {
|
||||||
return new XMLInputSource(is, true);
|
return new XMLInputSource(is, true);
|
||||||
@ -1216,7 +1225,7 @@ public class XMLEntityManager implements XMLComponent, XMLEntityResolver {
|
|||||||
fCatalogResolver = CatalogManager.catalogResolver(fCatalogFeatures);
|
fCatalogResolver = CatalogManager.catalogResolver(fCatalogFeatures);
|
||||||
}
|
}
|
||||||
String pid = (publicId != null? publicId : resourceIdentifier.getNamespace());
|
String pid = (publicId != null? publicId : resourceIdentifier.getNamespace());
|
||||||
xmlInputSource = resolveEntityOrURI(fCatalogResolver, pid, literalSystemId, baseSystemId);
|
xmlInputSource = resolveEntityOrURI(fCatalogFile, fCatalogResolver, pid, literalSystemId, baseSystemId);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 3: use the default JDK Catalog Resolver if Step 2's resolve is continue
|
// Step 3: use the default JDK Catalog Resolver if Step 2's resolve is continue
|
||||||
@ -1225,7 +1234,7 @@ public class XMLEntityManager implements XMLComponent, XMLEntityResolver {
|
|||||||
&& JdkXmlUtils.isResolveContinue(fCatalogFeatures)) {
|
&& JdkXmlUtils.isResolveContinue(fCatalogFeatures)) {
|
||||||
initJdkCatalogResolver();
|
initJdkCatalogResolver();
|
||||||
// unlike a custom catalog, the JDK Catalog only contains entity references
|
// unlike a custom catalog, the JDK Catalog only contains entity references
|
||||||
xmlInputSource = resolveEntity(fDefCR, publicId, literalSystemId, baseSystemId);
|
xmlInputSource = resolveEntity("JDKCatalog", fDefCR, publicId, literalSystemId, baseSystemId);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 4: default resolution if not resolved by a resolver and the RESOLVE
|
// Step 4: default resolution if not resolved by a resolver and the RESOLVE
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -387,20 +387,21 @@ public class SecuritySupport {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Strip off path from an URI
|
* Strips off path from a URI or file path.
|
||||||
*
|
*
|
||||||
* @param uri an URI with full path
|
* @param input a URI or file path
|
||||||
* @return the file name only
|
* @return the file name only
|
||||||
*/
|
*/
|
||||||
public static String sanitizePath(String uri) {
|
public static String sanitizePath(String input) {
|
||||||
if (uri == null) {
|
if (input == null) {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
int i = uri.lastIndexOf("/");
|
input = input.replace('\\', '/');
|
||||||
|
int i = input.lastIndexOf('/');
|
||||||
if (i > 0) {
|
if (i > 0) {
|
||||||
return uri.substring(i+1, uri.length());
|
return input.substring(i+1);
|
||||||
}
|
}
|
||||||
return "";
|
return input;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -0,0 +1,68 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2024, 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 sbd.test;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import javax.xml.parsers.SAXParser;
|
||||||
|
import javax.xml.parsers.SAXParserFactory;
|
||||||
|
import org.testng.Assert;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
import org.xml.sax.SAXParseException;
|
||||||
|
import org.xml.sax.helpers.DefaultHandler;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @test
|
||||||
|
* @bug 8326915
|
||||||
|
* @library /javax/xml/jaxp/libs /javax/xml/jaxp/unittest
|
||||||
|
* @run testng/othervm sbd.test.ExternalRefTest
|
||||||
|
* @summary Part of the Secure-By-Default (SBD) project. This test verifies issues
|
||||||
|
* and error message improvements related to external references.
|
||||||
|
*/
|
||||||
|
public class ExternalRefTest {
|
||||||
|
/**
|
||||||
|
* @bug 8326915
|
||||||
|
* Verifies that SAXParseException rather than NPE is thrown when a validating
|
||||||
|
* parser is restricted from processing external references.
|
||||||
|
* @throws Exception if the test fails
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testValidatingParser() throws Exception {
|
||||||
|
Assert.assertThrows(SAXParseException.class, () -> validateWithParser());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void validateWithParser() throws Exception {
|
||||||
|
SAXParserFactory spf = SAXParserFactory.newInstance();
|
||||||
|
|
||||||
|
spf.setNamespaceAware(true);
|
||||||
|
spf.setValidating(true);
|
||||||
|
|
||||||
|
SAXParser parser = spf.newSAXParser();
|
||||||
|
parser.setProperty("http://java.sun.com/xml/jaxp/properties/schemaLanguage",
|
||||||
|
"http://www.w3.org/2001/XMLSchema");
|
||||||
|
|
||||||
|
parser.setProperty("jdk.xml.jdkcatalog.resolve", "strict");
|
||||||
|
File xmlFile = new File(getClass().getResource("ExternalRefTest.xml").getPath());
|
||||||
|
|
||||||
|
parser.parse(xmlFile, new DefaultHandler());
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<test:a
|
||||||
|
xmlns:test="test"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="test ExternalRefTest.xsd">
|
||||||
|
<b>1</b>
|
||||||
|
<b>2</b>
|
||||||
|
</test:a>
|
@ -0,0 +1,15 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
|
||||||
|
<xsd:schema
|
||||||
|
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||||
|
xmlns="test"
|
||||||
|
targetNamespace="test">
|
||||||
|
|
||||||
|
<xsd:element name="a" type="A"/>
|
||||||
|
<xsd:complexType name="A">
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="b" type="xsd:string" maxOccurs="100"/>
|
||||||
|
</xsd:sequence>
|
||||||
|
</xsd:complexType>
|
||||||
|
|
||||||
|
</xsd:schema>
|
Loading…
Reference in New Issue
Block a user