提交 d968f0da 编写于 作者: K khazra

7171415: java.net.URI.equals/hashCode not consistent for some URIs

Summary: Rewrite URI.hashCode() to consider encoded characters, also reviewed by vitalyd@gmail.com, schlosna@gmail.com
Reviewed-by: chegar
上级 4d12b943
...@@ -1694,6 +1694,13 @@ public final class URI ...@@ -1694,6 +1694,13 @@ public final class URI
return c; 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) { private static boolean equal(String s, String t) {
if (s == t) return true; if (s == t) return true;
if ((s != null) && (t != null)) { if ((s != null) && (t != null)) {
...@@ -1744,7 +1751,26 @@ public final class URI ...@@ -1744,7 +1751,26 @@ public final class URI
private static int hash(int hash, String s) { private static int hash(int hash, String s) {
if (s == null) return hash; 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 // US-ASCII only
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
/* @test /* @test
* @summary Unit test for java.net.URI * @summary Unit test for java.net.URI
* @bug 4464135 4505046 4503239 4438319 4991359 4866303 7023363 7041800 * @bug 4464135 4505046 4503239 4438319 4991359 4866303 7023363 7041800
* 7171415
* @author Mark Reinhold * @author Mark Reinhold
*/ */
...@@ -1337,7 +1338,7 @@ public class Test { ...@@ -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++; testCount++;
if (!u.equals(v)) if (!u.equals(v))
throw new RuntimeException("Not equal: " + u + " " + v); throw new RuntimeException("Not equal: " + u + " " + v);
...@@ -1352,7 +1353,7 @@ public class Test { ...@@ -1352,7 +1353,7 @@ public class Test {
+ " [" + Integer.toHexString(uh) + "]"); + " [" + Integer.toHexString(uh) + "]");
} }
static void cmp0(Comparable u, Comparable v, boolean same) static void cmp0(URI u, URI v, boolean same)
throws URISyntaxException throws URISyntaxException
{ {
int c = u.compareTo(v); int c = u.compareTo(v);
...@@ -1361,18 +1362,18 @@ public class Test { ...@@ -1361,18 +1362,18 @@ public class Test {
+ " " + c); + " " + c);
} }
static void eq(Comparable u, Comparable v) throws URISyntaxException { static void eq(URI u, URI v) throws URISyntaxException {
eq0(u, v); eq0(u, v);
cmp0(u, v, true); cmp0(u, v, true);
} }
static void eqeq(Comparable u, Comparable v) { static void eqeq(URI u, URI v) {
testCount++; testCount++;
if (u != v) if (u != v)
throw new RuntimeException("Not ==: " + 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++; testCount++;
if (u.equals(v)) if (u.equals(v))
throw new RuntimeException("Equal: " + u + " " + v); throw new RuntimeException("Equal: " + u + " " + v);
...@@ -1383,17 +1384,17 @@ public class Test { ...@@ -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); ne0(u, v);
cmp0(u, v, false); 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); ne0(u, v);
int c = u.compareTo(v); int c = u.compareTo(v);
if (c >= 0) { if (c >= 0) {
show((URI)u); show(u);
show((URI)v); show(v);
throw new RuntimeException("Not less than: " + u + " " + v throw new RuntimeException("Not less than: " + u + " " + v
+ " " + c); + " " + c);
} }
...@@ -1404,7 +1405,7 @@ public class Test { ...@@ -1404,7 +1405,7 @@ public class Test {
lt(new URI(s), new URI(t)); 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); lt(v, u);
} }
...@@ -1430,6 +1431,8 @@ public class Test { ...@@ -1430,6 +1431,8 @@ public class Test {
lt(s, new URI("http://jag:cafebabe@java.sun.com:94/b/c/d?q#g")); 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")); 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")); 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("p", "s:p");
lt("s:p", "T:p"); lt("s:p", "T:p");
...@@ -1465,7 +1468,7 @@ public class Test { ...@@ -1465,7 +1468,7 @@ public class Test {
ObjectInputStream oi = new ObjectInputStream(bi); ObjectInputStream oi = new ObjectInputStream(bi);
try { try {
Object o = oi.readObject(); Object o = oi.readObject();
eq(u, (Comparable)o); eq(u, (URI)o);
} catch (ClassNotFoundException x) { } catch (ClassNotFoundException x) {
x.printStackTrace(); x.printStackTrace();
throw new RuntimeException(x.toString()); throw new RuntimeException(x.toString());
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册