mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-27 14:54:52 +02:00
5064980: URI compareTo inconsistent with equals for mixed-case escape sequences
Reviewed-by: chegar, dfuchs
This commit is contained in:
parent
fae788a200
commit
a1b2e1042c
2 changed files with 78 additions and 36 deletions
|
@ -1572,10 +1572,11 @@ public final class URI
|
|||
* component is undefined but the other is defined then the first is
|
||||
* considered to be less than the second. Unless otherwise noted, string
|
||||
* components are ordered according to their natural, case-sensitive
|
||||
* ordering as defined by the {@link java.lang.String#compareTo(Object)
|
||||
* ordering as defined by the {@link java.lang.String#compareTo(String)
|
||||
* String.compareTo} method. String components that are subject to
|
||||
* encoding are compared by comparing their raw forms rather than their
|
||||
* encoded forms.
|
||||
* encoded forms and the hexadecimal digits of escaped octets are compared
|
||||
* without regard to case.
|
||||
*
|
||||
* <p> The ordering of URIs is defined as follows: </p>
|
||||
*
|
||||
|
@ -1838,35 +1839,9 @@ public final class URI
|
|||
}
|
||||
|
||||
private static boolean equal(String s, String t) {
|
||||
if (s == t) return true;
|
||||
if ((s != null) && (t != null)) {
|
||||
if (s.length() != t.length())
|
||||
return false;
|
||||
if (s.indexOf('%') < 0)
|
||||
return s.equals(t);
|
||||
int n = s.length();
|
||||
for (int i = 0; i < n;) {
|
||||
char c = s.charAt(i);
|
||||
char d = t.charAt(i);
|
||||
if (c != '%') {
|
||||
if (c != d)
|
||||
return false;
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
if (d != '%')
|
||||
return false;
|
||||
i++;
|
||||
if (toLower(s.charAt(i)) != toLower(t.charAt(i)))
|
||||
return false;
|
||||
i++;
|
||||
if (toLower(s.charAt(i)) != toLower(t.charAt(i)))
|
||||
return false;
|
||||
i++;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
boolean testForEquality = true;
|
||||
int result = percentNormalizedComparison(s, t, testForEquality);
|
||||
return result == 0;
|
||||
}
|
||||
|
||||
// US-ASCII only
|
||||
|
@ -1920,11 +1895,61 @@ public final class URI
|
|||
}
|
||||
|
||||
private static int compare(String s, String t) {
|
||||
boolean testForEquality = false;
|
||||
int result = percentNormalizedComparison(s, t, testForEquality);
|
||||
return result;
|
||||
}
|
||||
|
||||
// The percentNormalizedComparison method does not verify two
|
||||
// characters that follow the % sign are hexadecimal digits.
|
||||
// Reason being:
|
||||
// 1) percentNormalizedComparison method is not called with
|
||||
// 'decoded' strings
|
||||
// 2) The only place where a percent can be followed by anything
|
||||
// other than hexadecimal digits is in the authority component
|
||||
// (for a IPv6 scope) and the whole authority component is case
|
||||
// insensitive.
|
||||
private static int percentNormalizedComparison(String s, String t,
|
||||
boolean testForEquality) {
|
||||
|
||||
if (s == t) return 0;
|
||||
if (s != null) {
|
||||
if (t != null)
|
||||
if (t != null) {
|
||||
if (s.indexOf('%') < 0) {
|
||||
return s.compareTo(t);
|
||||
else
|
||||
}
|
||||
int sn = s.length();
|
||||
int tn = t.length();
|
||||
if ((sn != tn) && testForEquality)
|
||||
return sn - tn;
|
||||
int val = 0;
|
||||
int n = sn < tn ? sn : tn;
|
||||
for (int i = 0; i < n; ) {
|
||||
char c = s.charAt(i);
|
||||
char d = t.charAt(i);
|
||||
val = c - d;
|
||||
if (c != '%') {
|
||||
if (val != 0)
|
||||
return val;
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
if (d != '%') {
|
||||
if (val != 0)
|
||||
return val;
|
||||
}
|
||||
i++;
|
||||
val = toLower(s.charAt(i)) - toLower(t.charAt(i));
|
||||
if (val != 0)
|
||||
return val;
|
||||
i++;
|
||||
val = toLower(s.charAt(i)) - toLower(t.charAt(i));
|
||||
if (val != 0)
|
||||
return val;
|
||||
i++;
|
||||
}
|
||||
return sn - tn;
|
||||
} else
|
||||
return +1;
|
||||
} else {
|
||||
return -1;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 2019, 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
|
||||
|
@ -1412,6 +1412,18 @@ public class Test {
|
|||
lt(new URI(s), new URI(t));
|
||||
}
|
||||
|
||||
static void gt0(URI u, URI v) throws URISyntaxException {
|
||||
ne0(u, v);
|
||||
int c = u.compareTo(v);
|
||||
if (c <= 0) {
|
||||
show(u);
|
||||
show(v);
|
||||
throw new RuntimeException("Not greater than: " + u + " " + v
|
||||
+ " " + c);
|
||||
}
|
||||
out.println(u + " < " + v);
|
||||
}
|
||||
|
||||
static void gt(URI u, URI v) throws URISyntaxException {
|
||||
lt(v, u);
|
||||
}
|
||||
|
@ -1423,10 +1435,12 @@ public class Test {
|
|||
URI o = new URI("mailto:foo@bar.com");
|
||||
URI r = new URI("reg://some%20registry/b/c/d?q#f");
|
||||
URI s = new URI("http://jag:cafebabe@java.sun.com:94/b/c/d?q#f");
|
||||
URI t = new URI("http://example.com/%5bsegment%5d");
|
||||
eq(o, o);
|
||||
lt(o, r);
|
||||
lt(s, o);
|
||||
lt(s, r);
|
||||
|
||||
eq(o, new URI("MaILto:foo@bar.com"));
|
||||
gt(o, new URI("mailto:foo@bar.COM"));
|
||||
eq(r, new URI("rEg://some%20registry/b/c/d?q#f"));
|
||||
|
@ -1436,6 +1450,9 @@ public class Test {
|
|||
gt(s, new URI("http://jag:CafeBabe@java.sun.com:94/b/c/d?q#f"));
|
||||
lt(s, new URI("http://jag:cafebabe@java.sun.com:94/b/c/d?r#f"));
|
||||
lt(s, new URI("http://jag:cafebabe@java.sun.com:94/b/c/d?q#g"));
|
||||
cmp0(t, new URI("http://example.com/%5Bsegment%5D"), true);
|
||||
gt0(t, new URI("http://example.com/%5BSegment%5D"));
|
||||
lt(new URI("http://example.com/%5Asegment%5D"), new URI("http://example.com/%5Bsegment%5D"));
|
||||
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"),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue