Summary
Update the java.net.URI::compareTo
specification and behavior to
adhere to the strong recommendation of the Comparable
interface, that
(x.compareTo(y)==0) == (x.equals(y))
, for URIs that contain
hexadecimal digits of escaped octets that differ only in case.
Problem
The URI::compareTo
method does not strictly follow the strong
recommendation of Comparable::compareTo
. Specifically, URI::compareTo
does not consider two URIs to be equal when they differ only in the case
of hexadecimal digits of escaped octets. While URI::equals
does
consider such URIs to be equal.
For example:
jshell> var uri1 = URI.create("http://example.com/%5bsegment%5d")
uri1 ==> http://example.com/%5bsegment%5d
jshell> var uri2 = URI.create("http://example.com/%5Bsegment%5D")
uri2 ==> http://example.com/%5Bsegment%5D
jshell> uri1.equals(uri2)
$4 ==> true
jshell> uri1.compareTo(uri2)
$5 ==> 32
The expectation is that uri1.compareTo(uri2)
should yield a result of
0
, indicating that the URIs compare equal, but it does not. This
expectation is derived from the fact that URI::compareTo
is specified
to satisfy the general contract of Comparable.compareTo
.
Solution
Update the specification and behavior of URI::compareTo
so that
hexadecimal digits of escaped octets are compared without regard to
case. Similar to, and consistent with, URI::equals
.
With this change, the above example of uri1.compareTo(uri2)
will
yield a result of 0
, indicating that the URIs compare equal.
Specification
src/java.base/share/classes/java/net/URI.java
/**
* Compares this URI to another object, which must be a URI.
*
* <p> When comparing corresponding components of two URIs, if one
* 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)
* 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>
*
* ...
*/
public int compareTo(URI that) { ... }
- csr of
-
JDK-5064980 URI compareTo inconsistent with equals for mixed-case escape sequences
-
- Resolved
-