mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-20 19:14:38 +02:00
8156845: Uri is getting incorrectly unwrapped
Reviewed-by: lancea
This commit is contained in:
parent
a3cdceaa83
commit
ec0e48670f
8 changed files with 131 additions and 68 deletions
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2015, 2016, 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
|
||||||
|
@ -56,7 +56,7 @@ final class CatalogResolverImpl implements CatalogResolver {
|
||||||
publicId = Normalizer.normalizePublicId(Normalizer.decodeURN(Util.getNotNullOrEmpty(publicId)));
|
publicId = Normalizer.normalizePublicId(Normalizer.decodeURN(Util.getNotNullOrEmpty(publicId)));
|
||||||
|
|
||||||
//check whether systemId is an urn
|
//check whether systemId is an urn
|
||||||
if (systemId != null && systemId.startsWith("urn:publicid:")) {
|
if (systemId != null && systemId.startsWith(Util.URN)) {
|
||||||
systemId = Normalizer.decodeURN(systemId);
|
systemId = Normalizer.decodeURN(systemId);
|
||||||
if (publicId != null && !publicId.equals(systemId)) {
|
if (publicId != null && !publicId.equals(systemId)) {
|
||||||
systemId = null;
|
systemId = null;
|
||||||
|
@ -67,7 +67,7 @@ final class CatalogResolverImpl implements CatalogResolver {
|
||||||
}
|
}
|
||||||
|
|
||||||
CatalogImpl c = (CatalogImpl)catalog;
|
CatalogImpl c = (CatalogImpl)catalog;
|
||||||
String resolvedSystemId = resolve(c, publicId, systemId);
|
String resolvedSystemId = Util.resolve(c, publicId, systemId);
|
||||||
|
|
||||||
if (resolvedSystemId != null) {
|
if (resolvedSystemId != null) {
|
||||||
return new InputSource(resolvedSystemId);
|
return new InputSource(resolvedSystemId);
|
||||||
|
@ -86,55 +86,4 @@ final class CatalogResolverImpl implements CatalogResolver {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Resolves the publicId or systemId using public or system entries in the catalog.
|
|
||||||
*
|
|
||||||
* The resolution follows the following rules determined by the prefer setting:
|
|
||||||
*
|
|
||||||
* prefer "system": attempts to resolve with a system entry;
|
|
||||||
* attempts to resolve with a public entry when only
|
|
||||||
* publicId is specified.
|
|
||||||
*
|
|
||||||
* prefer "public": attempts to resolve with a system entry;
|
|
||||||
* attempts to resolve with a public entry if no matching
|
|
||||||
* system entry is found.
|
|
||||||
* @param catalog the catalog
|
|
||||||
* @param publicId the publicId
|
|
||||||
* @param systemId the systemId
|
|
||||||
* @return the resolved systemId if a match is found, null otherwise
|
|
||||||
*/
|
|
||||||
String resolve(CatalogImpl catalog, String publicId, String systemId) {
|
|
||||||
String resolvedSystemId = null;
|
|
||||||
|
|
||||||
//search the current catalog
|
|
||||||
catalog.reset();
|
|
||||||
if (systemId != null) {
|
|
||||||
/*
|
|
||||||
If a system identifier is specified, it is used no matter how
|
|
||||||
prefer is set.
|
|
||||||
*/
|
|
||||||
resolvedSystemId = catalog.matchSystem(systemId);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (resolvedSystemId == null && publicId != null) {
|
|
||||||
resolvedSystemId = catalog.matchPublic(publicId);
|
|
||||||
}
|
|
||||||
|
|
||||||
//mark the catalog as having been searched before trying alternatives
|
|
||||||
catalog.markAsSearched();
|
|
||||||
|
|
||||||
//search alternative catalogs
|
|
||||||
if (resolvedSystemId == null) {
|
|
||||||
Iterator<Catalog> iter = catalog.catalogs().iterator();
|
|
||||||
while (iter.hasNext()) {
|
|
||||||
resolvedSystemId = resolve((CatalogImpl)iter.next(), publicId, systemId);
|
|
||||||
if (resolvedSystemId != null) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return resolvedSystemId;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2015, 2016, 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
|
||||||
|
@ -65,10 +65,19 @@ final class CatalogUriResolverImpl implements CatalogUriResolver {
|
||||||
|
|
||||||
if (href == null) return null;
|
if (href == null) return null;
|
||||||
|
|
||||||
|
String result = null;
|
||||||
CatalogImpl c = (CatalogImpl)catalog;
|
CatalogImpl c = (CatalogImpl)catalog;
|
||||||
String uri = Normalizer.normalizeURI(href);
|
String uri = Normalizer.normalizeURI(href);
|
||||||
String result;
|
//check whether uri is an urn
|
||||||
|
if (uri != null && uri.startsWith(Util.URN)) {
|
||||||
|
String publicId = Normalizer.decodeURN(uri);
|
||||||
|
if (publicId != null) {
|
||||||
|
result = Util.resolve(c, publicId, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//if no match with a public id, continue search for an URI
|
||||||
|
if (result == null) {
|
||||||
//remove fragment if any.
|
//remove fragment if any.
|
||||||
int hashPos = uri.indexOf("#");
|
int hashPos = uri.indexOf("#");
|
||||||
if (hashPos >= 0) {
|
if (hashPos >= 0) {
|
||||||
|
@ -77,6 +86,9 @@ final class CatalogUriResolverImpl implements CatalogUriResolver {
|
||||||
|
|
||||||
//search the current catalog
|
//search the current catalog
|
||||||
result = resolve(c, uri);
|
result = resolve(c, uri);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Report error or return the URI as is when no match is found
|
||||||
if (result == null) {
|
if (result == null) {
|
||||||
GroupEntry.ResolveType resolveType = c.getResolve();
|
GroupEntry.ResolveType resolveType = c.getResolve();
|
||||||
switch (resolveType) {
|
switch (resolveType) {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2015, 2016, 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
|
||||||
|
@ -298,6 +298,9 @@ class GroupEntry extends BaseEntry {
|
||||||
case PUBLIC:
|
case PUBLIC:
|
||||||
match = ((PublicEntry) entry).match(publicId);
|
match = ((PublicEntry) entry).match(publicId);
|
||||||
break;
|
break;
|
||||||
|
case URI:
|
||||||
|
match = ((UriEntry) entry).match(publicId);
|
||||||
|
break;
|
||||||
case GROUP:
|
case GROUP:
|
||||||
match = ((GroupEntry) entry).matchPublic(publicId);
|
match = ((GroupEntry) entry).matchPublic(publicId);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -100,7 +100,7 @@ class Normalizer {
|
||||||
} catch (UnsupportedEncodingException ex) {
|
} catch (UnsupportedEncodingException ex) {
|
||||||
CatalogMessages.reportRunTimeError(CatalogMessages.ERR_OTHER, ex);
|
CatalogMessages.reportRunTimeError(CatalogMessages.ERR_OTHER, ex);
|
||||||
}
|
}
|
||||||
return "urn:publicid:" + urn;
|
return Util.URN + urn;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -114,7 +114,7 @@ class Normalizer {
|
||||||
static String decodeURN(String urn) {
|
static String decodeURN(String urn) {
|
||||||
String publicId;
|
String publicId;
|
||||||
|
|
||||||
if (urn != null && urn.startsWith("urn:publicid:")) {
|
if (urn != null && urn.startsWith(Util.URN)) {
|
||||||
publicId = urn.substring(13);
|
publicId = urn.substring(13);
|
||||||
} else {
|
} else {
|
||||||
return urn;
|
return urn;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2015, 2016, 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
|
||||||
|
@ -52,8 +52,12 @@ final class UriEntry extends BaseEntry {
|
||||||
*/
|
*/
|
||||||
public void setName(String name) {
|
public void setName(String name) {
|
||||||
CatalogMessages.reportNPEOnNull("name", name);
|
CatalogMessages.reportNPEOnNull("name", name);
|
||||||
|
if (name.startsWith(Util.PUBLICID_PREFIX) || name.startsWith(Util.PUBLICID_PREFIX_ALT)) {
|
||||||
|
this.name = Normalizer.normalizePublicId(name);
|
||||||
|
} else {
|
||||||
this.name = Normalizer.normalizeURI(name);
|
this.name = Normalizer.normalizeURI(name);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the uri attribute. If the value of the uri attribute is relative, it
|
* Set the uri attribute. If the value of the uri attribute is relative, it
|
||||||
|
@ -72,6 +76,7 @@ final class UriEntry extends BaseEntry {
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the uri attribute.
|
* Get the uri attribute.
|
||||||
* @return The uri attribute value.
|
* @return The uri attribute value.
|
||||||
|
|
|
@ -31,6 +31,7 @@ import java.net.URISyntaxException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
|
import java.util.Iterator;
|
||||||
import jdk.xml.internal.SecuritySupport;
|
import jdk.xml.internal.SecuritySupport;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -38,6 +39,61 @@ import jdk.xml.internal.SecuritySupport;
|
||||||
* @since 9
|
* @since 9
|
||||||
*/
|
*/
|
||||||
class Util {
|
class Util {
|
||||||
|
final static String URN = "urn:publicid:";
|
||||||
|
final static String PUBLICID_PREFIX = "-//";
|
||||||
|
final static String PUBLICID_PREFIX_ALT = "+//";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds an entry in the catalog that matches with the publicId or systemId.
|
||||||
|
*
|
||||||
|
* The resolution follows the following rules determined by the prefer setting:
|
||||||
|
*
|
||||||
|
* prefer "system": attempts to resolve with a system entry;
|
||||||
|
* attempts to resolve with a public entry when only
|
||||||
|
* publicId is specified.
|
||||||
|
*
|
||||||
|
* prefer "public": attempts to resolve with a system entry;
|
||||||
|
* attempts to resolve with a public entry if no matching
|
||||||
|
* system entry is found.
|
||||||
|
* @param catalog the catalog
|
||||||
|
* @param publicId the publicId
|
||||||
|
* @param systemId the systemId
|
||||||
|
* @return the resolved systemId if a match is found, null otherwise
|
||||||
|
*/
|
||||||
|
static String resolve(CatalogImpl catalog, String publicId, String systemId) {
|
||||||
|
String resolvedSystemId = null;
|
||||||
|
|
||||||
|
//search the current catalog
|
||||||
|
catalog.reset();
|
||||||
|
if (systemId != null) {
|
||||||
|
/*
|
||||||
|
If a system identifier is specified, it is used no matter how
|
||||||
|
prefer is set.
|
||||||
|
*/
|
||||||
|
resolvedSystemId = catalog.matchSystem(systemId);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (resolvedSystemId == null && publicId != null) {
|
||||||
|
resolvedSystemId = catalog.matchPublic(publicId);
|
||||||
|
}
|
||||||
|
|
||||||
|
//mark the catalog as having been searched before trying alternatives
|
||||||
|
catalog.markAsSearched();
|
||||||
|
|
||||||
|
//search alternative catalogs
|
||||||
|
if (resolvedSystemId == null) {
|
||||||
|
Iterator<Catalog> iter = catalog.catalogs().iterator();
|
||||||
|
while (iter.hasNext()) {
|
||||||
|
resolvedSystemId = resolve((CatalogImpl)iter.next(), publicId, systemId);
|
||||||
|
if (resolvedSystemId != null) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return resolvedSystemId;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resolves the specified file path to an absolute systemId. If it is
|
* Resolves the specified file path to an absolute systemId. If it is
|
||||||
|
|
|
@ -34,6 +34,7 @@ import javax.xml.catalog.CatalogUriResolver;
|
||||||
import javax.xml.parsers.ParserConfigurationException;
|
import javax.xml.parsers.ParserConfigurationException;
|
||||||
import javax.xml.parsers.SAXParser;
|
import javax.xml.parsers.SAXParser;
|
||||||
import javax.xml.parsers.SAXParserFactory;
|
import javax.xml.parsers.SAXParserFactory;
|
||||||
|
import javax.xml.transform.Source;
|
||||||
import org.testng.Assert;
|
import org.testng.Assert;
|
||||||
import org.testng.annotations.BeforeClass;
|
import org.testng.annotations.BeforeClass;
|
||||||
import org.testng.annotations.DataProvider;
|
import org.testng.annotations.DataProvider;
|
||||||
|
@ -67,6 +68,24 @@ public class CatalogTest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @bug 8156845
|
||||||
|
* Verifies that an URI reference with a urn:publicid is correctly resolved
|
||||||
|
* with an uri entry with a publicId.
|
||||||
|
*
|
||||||
|
* @param expectedFile is not used in this test, it's kept since we're
|
||||||
|
* copying the JCK test and its dataProvider. This test may be reused for
|
||||||
|
* other cases in that test.
|
||||||
|
*/
|
||||||
|
@Test(dataProvider = "resolveUri")
|
||||||
|
public void testMatch1(String cFile, String href, String expectedFile, String expectedUri, String msg) {
|
||||||
|
String catalogFile = getClass().getResource(cFile).getFile();
|
||||||
|
CatalogUriResolver cur = CatalogManager.catalogUriResolver(CatalogFeatures.defaults(), catalogFile);
|
||||||
|
Source source = cur.resolve(href, null);
|
||||||
|
Assert.assertNotNull(source, "Source returned is null");
|
||||||
|
Assert.assertEquals(expectedUri, source.getSystemId(), msg);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @bug 8154220
|
* @bug 8154220
|
||||||
* Verifies that the file input is validated properly. Valid input includes
|
* Verifies that the file input is validated properly. Valid input includes
|
||||||
|
@ -329,6 +348,21 @@ public class CatalogTest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
DataProvider: used to verify CatalogUriResolver's resolve function.
|
||||||
|
Data columns:
|
||||||
|
catalog, uri or publicId, expectedFile, expectedUri, msg
|
||||||
|
|
||||||
|
This DataProvider is copied from JCK ResolveTests' dataMatch1
|
||||||
|
*/
|
||||||
|
@DataProvider(name = "resolveUri")
|
||||||
|
Object[][] getDataForUriResolver() {
|
||||||
|
return new Object[][]{
|
||||||
|
{"uri.xml", "urn:publicid:-:Acme,+Inc.:DTD+Book+Version+1.0", null, "http://local/base/dtd/book.dtd", "Uri in publicId namespace is incorrectly unwrapped"},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
DataProvider: used to verify hierarchical catalogs. Refer to JCK test
|
DataProvider: used to verify hierarchical catalogs. Refer to JCK test
|
||||||
hierarchyOfCatFiles2.
|
hierarchyOfCatFiles2.
|
||||||
|
|
4
jaxp/test/javax/xml/jaxp/unittest/catalog/uri.xml
Normal file
4
jaxp/test/javax/xml/jaxp/unittest/catalog/uri.xml
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog" xml:base="http://local/base/dtd/">
|
||||||
|
<uri name="-//Acme, Inc.//DTD Book Version 1.0" uri="book.dtd"/>
|
||||||
|
</catalog>
|
Loading…
Add table
Add a link
Reference in a new issue