Description
FULL PRODUCT VERSION :
A DESCRIPTION OF THE PROBLEM :
These two URIs are identical, except for the url-encoded character at the end that does not use the same case :
http://www.example.com/%C2
http://www.example.com/%c2
According to the URI RFC section 6.2.2.1 (http://tools.ietf.org/html/rfc3986#section-6.2.2.1), they should be considered equal.
They are indeed equal when using java.net.URI.equals(), but do not return the same hashCode using java.net.URI.hashCode().
The bug occurs for any two URIs with differences only in the case of the url-encoded characters.
The problem lies in the implementation of URI.hash(int,String), that does not implement a mecanism to normalize url-encoded characters for comparison, when URI.equal(String,String) does.
There should also be a method on URI to normalize the url-encoded characters (URI.normalize() does not)
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
URI uri1 = URI.create("http://www.example.com/%C2");
URI uri2 = URI.create("http://www.example.com/%c2");
System.out.println(uri1.equals(uri2));
System.out.println(uri1.hashCode() == uri2.hashCode());
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
true
true
ACTUAL -
true
false
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
URI upperCaseUrlEncodedChar = URI.create("http://www.example.com/%C2");
URI lowerCaseUrlEncodedChar = URI.create("http://www.example.com/%c2");
assert upperCaseUrlEncodedChar.hashCode() == lowerCaseUrlEncodedChar.hashCode(); //OK
assert upperCaseUrlEncodedChar.equals(lowerCaseUrlEncodedChar); //KO
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Normalize the string representation of the URI before creating the URI object
A DESCRIPTION OF THE PROBLEM :
These two URIs are identical, except for the url-encoded character at the end that does not use the same case :
http://www.example.com/%C2
http://www.example.com/%c2
According to the URI RFC section 6.2.2.1 (http://tools.ietf.org/html/rfc3986#section-6.2.2.1), they should be considered equal.
They are indeed equal when using java.net.URI.equals(), but do not return the same hashCode using java.net.URI.hashCode().
The bug occurs for any two URIs with differences only in the case of the url-encoded characters.
The problem lies in the implementation of URI.hash(int,String), that does not implement a mecanism to normalize url-encoded characters for comparison, when URI.equal(String,String) does.
There should also be a method on URI to normalize the url-encoded characters (URI.normalize() does not)
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
URI uri1 = URI.create("http://www.example.com/%C2");
URI uri2 = URI.create("http://www.example.com/%c2");
System.out.println(uri1.equals(uri2));
System.out.println(uri1.hashCode() == uri2.hashCode());
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
true
true
ACTUAL -
true
false
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
URI upperCaseUrlEncodedChar = URI.create("http://www.example.com/%C2");
URI lowerCaseUrlEncodedChar = URI.create("http://www.example.com/%c2");
assert upperCaseUrlEncodedChar.hashCode() == lowerCaseUrlEncodedChar.hashCode(); //OK
assert upperCaseUrlEncodedChar.equals(lowerCaseUrlEncodedChar); //KO
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Normalize the string representation of the URI before creating the URI object