/* * Copyright (c) 2000, 2022, 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.
*/
/* @test * @summary Unit test for java.net.URI * @bug 4464135 4505046 4503239 4438319 4991359 4866303 7023363 7041800 * 7171415 6339649 6933879 8037396 8272072 8051627 8297687 * @author Mark Reinhold
*/
String input;
URI uri = null;
URI originalURI;
URI base = null; // Base for resolution/relativization
String op = null; // Op performed if uri != originalURI int checked = 0; // Mask for checked properties int failed = 0; // Mask for failed properties
Exception exc = null;
static Test testCreate(String s) { returnnew Test(s, false);
}
boolean parsed() { return uri != null;
}
boolean resolved() { return base != null;
}
URI uri() { return uri;
}
// Operations on Test instances // // These are short so as to make test cases compact. // // s Scheme // sp Scheme-specific part // spd Scheme-specific part, decoded // o Opaque part (isOpaque() && ssp matches) // g reGistry (authority matches, and host is not defined) // gd reGistry, decoded // u User info // ud User info, decoded // h Host // n port Number // p Path // pd Path, decoded // q Query // qd Query, decoded // f Fragment // fd Fragment, decoded // // rslv Resolve against given base // rtvz Relativize // psa Parse server Authority // norm Normalize // ta ASCII form // // x Check that parse failed as expected // z End -- ensure that unchecked components are null
privatevoid checkEmpty(String s, int prop) { if (((checked & prop) == 0) && (s != null))
failed |= prop;
}
// Check identity for the seven-argument URI constructor // void checkURI7() { // Only works on hierarchical URIs if (uri.isOpaque()) return; // Only works with server-based authorities if ((uri.getAuthority() == null)
!= ((uri.getUserInfo() == null) && (uri.getHost() == null))) return; // Not true if non-US-ASCII chars are encoded unnecessarily if (uri.getPath().indexOf('\u20AC') >= 0) return; try {
URI u2 = new URI(uri.getScheme(), uri.getUserInfo(),
uri.getHost(), uri.getPort(), uri.getPath(),
uri.getQuery(), uri.getFragment()); if (!uri.equals(u2))
failed |= IDENT_URI7;
} catch (URISyntaxException x) {
failed |= IDENT_URI7;
}
}
// Check identity for the five-argument URI constructor // void checkURI5() { // Only works on hierarchical URIs if (uri.isOpaque()) return; try {
URI u2 = new URI(uri.getScheme(), uri.getAuthority(),
uri.getPath(), uri.getQuery(), uri.getFragment()); if (!uri.equals(u2))
failed |= IDENT_URI5;
} catch (URISyntaxException x) {
failed |= IDENT_URI5;
}
}
// Check identity for the three-argument URI constructor // void checkURI3() { try {
URI u2 = new URI(uri.getScheme(),
uri.getSchemeSpecificPart(),
uri.getFragment()); if (!uri.equals(u2))
failed |= IDENT_URI3;
} catch (URISyntaxException x) {
failed |= IDENT_URI3;
}
}
// Check all identities mentioned in the URI class specification // void checkIdentities() { if (input != null) { if (!uri.toString().equals(input))
failed |= IDENT_STR;
} try { if (!(new URI(uri.toString())).equals(uri))
failed |= IDENT_URI1;
} catch (URISyntaxException x) {
failed |= IDENT_URI1;
}
// Remaining identities fail if "//" given but authority is undefined if ((uri.getAuthority() == null)
&& (uri.getSchemeSpecificPart() != null)
&& (uri.getSchemeSpecificPart().startsWith("///")
|| uri.getSchemeSpecificPart().startsWith("//?")
|| uri.getSchemeSpecificPart().equals("//"))) return;
// Remaining identities fail if ":" given but port is undefined if ((uri.getHost() != null)
&& (uri.getAuthority() != null)
&& (uri.getAuthority().equals(uri.getHost() + ":"))) return;
// Remaining identities fail if non-US-ASCII chars are encoded // unnecessarily if ((uri.getPath() != null) && uri.getPath().indexOf('\u20AC') >= 0) return;
checkURI3();
checkURI5();
checkURI7();
}
// Check identities, check that unchecked component properties are not // defined, and report any failures //
Test z() { if (!parsed()) {
report(); returnthis;
}
// #s (current document)#s // DEVIATION: Lone fragment parses as relative URI with empty path
test("#s")
.p("").f("s").z()
.rslv(base).s("http").h("a").p("/b/c/d;p").f("s").q("q").z();
URI base = new URI("s://h/a/b");
URI rbase = new URI("a/b/c/d");
header("Corner cases");
// The empty URI parses as a relative URI with an empty path
test("").p("").z()
.rslv(base).s("s").h("h").p("/a/").z();
// Resolving solo queries and fragments
test("#f").p("").f("f").z()
.rslv(base).s("s").h("h").p("/a/b").f("f").z();
test("?q").p("").q("q").z()
.rslv(base).s("s").h("h").p("/a/").q("q").z();
// Fragment is not part of ssp
test("p#f").p("p").f("f").sp("p").z();
test("s:p#f").s("s").o("p").f("f").z();
test("p#f")
.rslv(base).s("s").h("h").p("/a/p").f("f").sp("//h/a/p").z();
test("").p("").sp("").z();
header("Emptiness");
// Components that may be empty
test("///p").p("/p").z(); // Authority (w/ path)
test("//@h/p").u("").h("h").p("/p").z(); // User info
test("//h:/p").h("h").p("/p").z(); // Port
test("//h").h("h").p("").z(); // Path
test("//h?q").h("h").p("").q("q").z(); // Path (w/query)
test("//?q").p("").q("q").z(); // Authority (w/query)
test("//#f").p("").f("f").z(); // Authority (w/fragment)
test("p?#").p("p").q("").f("").z(); // Query & fragment
// Components that may not be empty
test(":").x().z(); // Scheme
test("x:").x().z(); // Hier/opaque
test("//").x().z(); // Authority (w/o path)
header("Resolution, normalization, and relativization");
// Normalization of already normalized URI should yield the // same URI
URI u1 = URI.create("s://h/../p");
URI u2 = u1.normalize();
eq(u1, u2);
eqeq(u1, u2);
// 4648111 - Escapes quoted by toString after resolution
uri = new URI("http://a/b/c/d;p?q");
test("/p%20p")
.rslv(uri).s("http").h("a").p("/p%20p").ts("http://a/p%20p").z();
// 4464135: Forbid unwise characters throughout opaque part
test("foo:x{bar").x().z();
test("foo:{bar").x().z();
// 4991359 and 4866303: bad quoting by defineSchemeSpecificPart()
URI base = new URI ("http://host/foo%20bar/a/b/c/d");
test ("resolve")
.rslv(base).spd("//host/foo bar/a/b/c/resolve")
.sp("//host/foo%20bar/a/b/c/resolve").s("http")
.pd("/foo bar/a/b/c/resolve").h("host")
.p("/foo%20bar/a/b/c/resolve").z();
staticvoid usage() {
out.println("Usage:");
out.println(" java Test -- Runs all tests in this file");
out.println(" java Test -- Parses uri, shows components");
out.println(" java Test -- Parses uri and base, then resolves");
out.println(" uri against base");
}
staticvoid clargs(String base, String uri) {
URI b = null, u; try { if (base != null) {
b = new URI(base);
out.println(base);
show(b);
}
u = new URI(uri);
out.println(uri);
show(u); if (base != null) {
URI r = b.resolve(u);
out.println(r);
show(r);
}
} catch (URISyntaxException x) {
show("ERROR", x);
x.printStackTrace(out);
}
}
// miscellaneous bugs/rfes that don't fit in with the test framework
privatestaticvoid b8297687() { // constructors that take a hostname should fail
test("ftps", "p.e.local|SIT@p.e.local", "/path", null)
.x().z();
test("ftps", null,"p.e.local|SIT@p.e.local", -1, "/path", null, null)
.x().z(); // constructors that take an authority component should succeed
test("ftps", "p.e.local|SIT@p.e.local", "/path", null,null)
.s("ftps")
.sp("//p.e.local%7CSIT@p.e.local/path")
.spd("//p.e.local|SIT@p.e.local/path")
.u("p.e.local%7CSIT")
.ud("p.e.local|SIT")
.h("p.e.local")
.n(-1)
.p("/path")
.pd("/path")
.z();
// check index in exception for constructors that should fail try {
URI uri = new URI("ftps", "p.e.local|SIT@p.e.local", "/path", null); thrownew AssertionError("Expected URISyntaxException not thrown for " + uri);
} catch (URISyntaxException ex) { if (ex.getMessage().contains("at index 16")) {
System.out.println("Got expected exception: " + ex);
} else { thrownew AssertionError("Exception does not point at index 16", ex);
}
}
testCount++;
// check index in exception for constructors that should fail try {
URI uri = new URI("ftps", null, "p.e.local|SIT@p.e.local", -1, "/path", null, null); thrownew AssertionError("Expected URISyntaxException not thrown for " + uri);
} catch (URISyntaxException ex) { if (ex.getMessage().contains("at index 16")) {
System.out.println("Got expected exception: " + ex);
} else { thrownew AssertionError("Exception does not point at index 16", ex);
}
}
testCount++;
}
// 6339649 - include detail message from nested exception privatestaticvoid b6339649() { try {
URI uri = URI.create("http://nowhere.net/should not be permitted");
} catch (IllegalArgumentException e) { if ("".equals(e.getMessage()) || e.getMessage() == null) { thrownew RuntimeException ("No detail message");
}
}
testCount++;
}
// 6933879 - check that "." and "_" characters are allowed in IPv6 scope_id. privatestaticvoid b6933879() { final String HOST = "fe80::c00:16fe:cebe:3214%eth1.12_55";
URI uri; try {
uri = new URI("http", null, HOST, 10, "/", null, null);
} catch (URISyntaxException ex) { thrownew AssertionError("Should not happen", ex);
}
eq("[" + HOST + "]", uri.getHost());
}
// 8051627 - Invariants about java.net.URI resolve and relativize are wrong privatestaticvoid b8051627() { try { // Let u be a normalized absolute URI u which ends with "/" and // v be a normalized relative URI v which does not start with "." or "/", then // u.relativize(u.resolve(v)).equals(v) should be true
reltivizeAfterResolveTest("http://a/b/", "c/d", "c/d");
reltivizeAfterResolveTest("http://a/b/", "g;x?y#s", "g;x?y#s");
// when the URI condition is not met, u.relativize(u.resolve(v)).equals(v) may be false // In the following examples, that should be false
reltivizeAfterResolveTest("http://a/b", "c/d", "http://a/c/d");
reltivizeAfterResolveTest("http://a/b/", "../c/d", "http://a/c/d");
reltivizeAfterResolveTest("http://a/b/", "/c/d", "http://a/c/d");
reltivizeAfterResolveTest("http://a/b/", "http://a/b/c/d", "c/d");
// Let u be a normalized absolute URI u which ends with "/" and // v be a normalized absolute URI v, then // u.resolve(u.relativize(v)).equals(v) should be true
resolveAfterRelativizeTest("http://a/b/", "http://a/b/c/d", "http://a/b/c/d");
resolveAfterRelativizeTest("http://a/b/", "http://a/b/c/g;x?y#s", "http://a/b/c/g;x?y#s");
// when the URI condition is not met, u.resolve(u.relativize(v)).equals(v) may be false // In the following examples, that should be false
resolveAfterRelativizeTest("http://a/b", "http://a/b/c/d", "http://a/c/d");
resolveAfterRelativizeTest("http://a/b/", "c/d", "http://a/b/c/d");
} catch (URISyntaxException e) { thrownew AssertionError("shouldn't ever happen", e);
}
} privatestaticvoid reltivizeAfterResolveTest(String base, String target, String expected) throws URISyntaxException {
URI baseURI = URI.create(base);
URI targetURI = URI.create(target);
eq(URI.create(expected), baseURI.relativize(baseURI.resolve(targetURI)));
} privatestaticvoid resolveAfterRelativizeTest(String base, String target, String expected) throws URISyntaxException {
URI baseURI = URI.create(base);
URI targetURI = URI.create(target);
eq(URI.create(expected), baseURI.resolve(baseURI.relativize(targetURI)));
}
// 8272072 - Resolving URI relative path with no "/" may lead to incorrect toString privatestaticvoid b8272072() { try {
URI baseURI = new URI("http://example.com");
URI relativeURI = new URI("test");
URI resolvedURI = baseURI.resolve(relativeURI);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.