Adjust Uri host parsing to use last instead of first @.
Malformed authority segments can currently cause the parser to produce a hostname that doesn't match the hostname produced by the WHATWG URL parsing algorithm* used by browsers, which means that a URL could be seen as having a "safe" host when checked by an Android app but actually visit a different host when passed to a browser. The WHATWG URL parsing algorithm always produces a hostname based on the last @ in the authority segment, so we do the same. * https://url.spec.whatwg.org/#authority-state resets the "buffer", which is being used to build up the host name, each time an @ is found, so it has the effect of using the content between the final @ and the end of the authority section as the hostname. Bug: 68341964 Test: vogar android.net.UriTest (on NYC branch) Test: cts -m CtsNetTestCases (on NYC branch) Change-Id: Idca79f35a886de042c94d6ab66787c2e98ac8376
This commit is contained in:
@@ -1060,7 +1060,7 @@ public abstract class Uri implements Parcelable, Comparable<Uri> {
|
||||
return null;
|
||||
}
|
||||
|
||||
int end = authority.indexOf('@');
|
||||
int end = authority.lastIndexOf('@');
|
||||
return end == NOT_FOUND ? null : authority.substring(0, end);
|
||||
}
|
||||
|
||||
@@ -1084,7 +1084,7 @@ public abstract class Uri implements Parcelable, Comparable<Uri> {
|
||||
}
|
||||
|
||||
// Parse out user info and then port.
|
||||
int userInfoSeparator = authority.indexOf('@');
|
||||
int userInfoSeparator = authority.lastIndexOf('@');
|
||||
int portSeparator = authority.indexOf(':', userInfoSeparator);
|
||||
|
||||
String encodedHost = portSeparator == NOT_FOUND
|
||||
@@ -1110,7 +1110,7 @@ public abstract class Uri implements Parcelable, Comparable<Uri> {
|
||||
|
||||
// Make sure we look for the port separtor *after* the user info
|
||||
// separator. We have URLs with a ':' in the user info.
|
||||
int userInfoSeparator = authority.indexOf('@');
|
||||
int userInfoSeparator = authority.lastIndexOf('@');
|
||||
int portSeparator = authority.indexOf(':', userInfoSeparator);
|
||||
|
||||
if (portSeparator == NOT_FOUND) {
|
||||
|
||||
@@ -187,6 +187,11 @@ public class UriTest extends TestCase {
|
||||
uri = Uri.parse("http://localhost");
|
||||
assertEquals("localhost", uri.getHost());
|
||||
assertEquals(-1, uri.getPort());
|
||||
|
||||
uri = Uri.parse("http://a:a@example.com:a@example2.com/path");
|
||||
assertEquals("a:a@example.com:a@example2.com", uri.getAuthority());
|
||||
assertEquals("example2.com", uri.getHost());
|
||||
assertEquals(-1, uri.getPort());
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
|
||||
Reference in New Issue
Block a user