Skip to content

Commit

Permalink
8326915: NPE when a validating parser is restricted
Browse files Browse the repository at this point in the history
Reviewed-by: lancea, naoto
  • Loading branch information
JoeWang-Java committed Mar 2, 2024
1 parent f62f2ad commit a3d51d2
Show file tree
Hide file tree
Showing 5 changed files with 116 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@
* @author K.Venugopal SUN Microsystems
* @author Neeraj Bajaj SUN Microsystems
* @author Sunitha Reddy SUN Microsystems
* @LastModified: Jan 2024
* @LastModified: Feb 2024
*/
public class XMLEntityManager implements XMLComponent, XMLEntityResolver {

Expand Down Expand Up @@ -1118,8 +1118,9 @@ private InputSource resolveWithCatalog(CatalogResolver cr, String cFile,
* 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);
private XMLInputSource resolveEntityOrURI(String catalogName, CatalogResolver cr,
String publicId, String systemId, String base) {
XMLInputSource xis = resolveEntity(catalogName, cr, publicId, systemId, base);

if (xis != null) {
return xis;
Expand All @@ -1137,13 +1138,21 @@ private XMLInputSource resolveEntityOrURI(CatalogResolver cr, String publicId, S
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;
try {
if (publicId != null || systemId != null) {
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()) {
return new XMLInputSource(is, true);
Expand Down Expand Up @@ -1216,7 +1225,7 @@ public XMLInputSource resolveEntity(XMLResourceIdentifier resourceIdentifier) th
fCatalogResolver = CatalogManager.catalogResolver(fCatalogFeatures);
}
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
Expand All @@ -1225,7 +1234,7 @@ public XMLInputSource resolveEntity(XMLResourceIdentifier resourceIdentifier) th
&& JdkXmlUtils.isResolveContinue(fCatalogFeatures)) {
initJdkCatalogResolver();
// 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
Expand Down
17 changes: 9 additions & 8 deletions src/java.xml/share/classes/jdk/xml/internal/SecuritySupport.java
Original file line number Diff line number Diff line change
@@ -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.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -387,20 +387,21 @@ static long getLastModified(final File f) {
}

/**
* 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
*/
public static String sanitizePath(String uri) {
if (uri == null) {
public static String sanitizePath(String input) {
if (input == null) {
return "";
}
int i = uri.lastIndexOf("/");
input = input.replace('\\', '/');
int i = input.lastIndexOf('/');
if (i > 0) {
return uri.substring(i+1, uri.length());
return input.substring(i+1);
}
return "";
return input;
}

/**
Expand Down
68 changes: 68 additions & 0 deletions test/jaxp/javax/xml/jaxp/unittest/sbd/test/ExternalRefTest.java
Original file line number Diff line number Diff line change
@@ -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());
}
}
Original file line number Diff line number Diff line change
@@ -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>
15 changes: 15 additions & 0 deletions test/jaxp/javax/xml/jaxp/unittest/sbd/test/ExternalRefTest.xsd
Original file line number Diff line number Diff line change
@@ -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>

1 comment on commit a3d51d2

@openjdk-notifier
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.