mirror of
https://github.com/openjdk/jdk.git
synced 2026-04-22 21:00:31 +00:00
7171415: java.net.URI.equals/hashCode not consistent for some URIs
Rewrite URI.hashCode() to consider encoded characters, also reviewed by vitalyd@gmail.com, schlosna@gmail.com Reviewed-by: chegar
This commit is contained in:
parent
fe16fc39d6
commit
8f2bd71dc9
@ -1694,6 +1694,13 @@ public final class URI
|
||||
return c;
|
||||
}
|
||||
|
||||
// US-ASCII only
|
||||
private static int toUpper(char c) {
|
||||
if ((c >= 'a') && (c <= 'z'))
|
||||
return c - ('a' - 'A');
|
||||
return c;
|
||||
}
|
||||
|
||||
private static boolean equal(String s, String t) {
|
||||
if (s == t) return true;
|
||||
if ((s != null) && (t != null)) {
|
||||
@ -1744,7 +1751,26 @@ public final class URI
|
||||
|
||||
private static int hash(int hash, String s) {
|
||||
if (s == null) return hash;
|
||||
return hash * 127 + s.hashCode();
|
||||
return s.indexOf('%') < 0 ? hash * 127 + s.hashCode()
|
||||
: normalizedHash(hash, s);
|
||||
}
|
||||
|
||||
|
||||
private static int normalizedHash(int hash, String s) {
|
||||
int h = 0;
|
||||
for (int index = 0; index < s.length(); index++) {
|
||||
char ch = s.charAt(index);
|
||||
h = 31 * h + ch;
|
||||
if (ch == '%') {
|
||||
/*
|
||||
* Process the next two encoded characters
|
||||
*/
|
||||
for (int i = index + 1; i < index + 3; i++)
|
||||
h = 31 * h + toUpper(s.charAt(i));
|
||||
index += 2;
|
||||
}
|
||||
}
|
||||
return hash * 127 + h;
|
||||
}
|
||||
|
||||
// US-ASCII only
|
||||
|
||||
@ -24,6 +24,7 @@
|
||||
/* @test
|
||||
* @summary Unit test for java.net.URI
|
||||
* @bug 4464135 4505046 4503239 4438319 4991359 4866303 7023363 7041800
|
||||
* 7171415
|
||||
* @author Mark Reinhold
|
||||
*/
|
||||
|
||||
@ -1337,7 +1338,7 @@ public class Test {
|
||||
}
|
||||
|
||||
|
||||
static void eq0(Comparable u, Comparable v) throws URISyntaxException {
|
||||
static void eq0(URI u, URI v) throws URISyntaxException {
|
||||
testCount++;
|
||||
if (!u.equals(v))
|
||||
throw new RuntimeException("Not equal: " + u + " " + v);
|
||||
@ -1352,7 +1353,7 @@ public class Test {
|
||||
+ " [" + Integer.toHexString(uh) + "]");
|
||||
}
|
||||
|
||||
static void cmp0(Comparable u, Comparable v, boolean same)
|
||||
static void cmp0(URI u, URI v, boolean same)
|
||||
throws URISyntaxException
|
||||
{
|
||||
int c = u.compareTo(v);
|
||||
@ -1361,18 +1362,18 @@ public class Test {
|
||||
+ " " + c);
|
||||
}
|
||||
|
||||
static void eq(Comparable u, Comparable v) throws URISyntaxException {
|
||||
static void eq(URI u, URI v) throws URISyntaxException {
|
||||
eq0(u, v);
|
||||
cmp0(u, v, true);
|
||||
}
|
||||
|
||||
static void eqeq(Comparable u, Comparable v) {
|
||||
static void eqeq(URI u, URI v) {
|
||||
testCount++;
|
||||
if (u != v)
|
||||
throw new RuntimeException("Not ==: " + u + " " + v);
|
||||
}
|
||||
|
||||
static void ne0(Comparable u, Comparable v) throws URISyntaxException {
|
||||
static void ne0(URI u, URI v) throws URISyntaxException {
|
||||
testCount++;
|
||||
if (u.equals(v))
|
||||
throw new RuntimeException("Equal: " + u + " " + v);
|
||||
@ -1383,17 +1384,17 @@ public class Test {
|
||||
+ "]");
|
||||
}
|
||||
|
||||
static void ne(Comparable u, Comparable v) throws URISyntaxException {
|
||||
static void ne(URI u, URI v) throws URISyntaxException {
|
||||
ne0(u, v);
|
||||
cmp0(u, v, false);
|
||||
}
|
||||
|
||||
static void lt(Comparable u, Comparable v) throws URISyntaxException {
|
||||
static void lt(URI u, URI v) throws URISyntaxException {
|
||||
ne0(u, v);
|
||||
int c = u.compareTo(v);
|
||||
if (c >= 0) {
|
||||
show((URI)u);
|
||||
show((URI)v);
|
||||
show(u);
|
||||
show(v);
|
||||
throw new RuntimeException("Not less than: " + u + " " + v
|
||||
+ " " + c);
|
||||
}
|
||||
@ -1404,7 +1405,7 @@ public class Test {
|
||||
lt(new URI(s), new URI(t));
|
||||
}
|
||||
|
||||
static void gt(Comparable u, Comparable v) throws URISyntaxException {
|
||||
static void gt(URI u, URI v) throws URISyntaxException {
|
||||
lt(v, u);
|
||||
}
|
||||
|
||||
@ -1430,6 +1431,8 @@ public class Test {
|
||||
lt(s, new URI("http://jag:cafebabe@java.sun.com:94/b/c/d?q#g"));
|
||||
eq(new URI("http://host/a%00bcd"), new URI("http://host/a%00bcd"));
|
||||
ne(new URI("http://host/a%00bcd"), new URI("http://host/aZ00bcd"));
|
||||
eq0(new URI("http://host/abc%e2def%C3ghi"),
|
||||
new URI("http://host/abc%E2def%c3ghi"));
|
||||
|
||||
lt("p", "s:p");
|
||||
lt("s:p", "T:p");
|
||||
@ -1465,7 +1468,7 @@ public class Test {
|
||||
ObjectInputStream oi = new ObjectInputStream(bi);
|
||||
try {
|
||||
Object o = oi.readObject();
|
||||
eq(u, (Comparable)o);
|
||||
eq(u, (URI)o);
|
||||
} catch (ClassNotFoundException x) {
|
||||
x.printStackTrace();
|
||||
throw new RuntimeException(x.toString());
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user