Skip to content

Commit

Permalink
Adjust Uri host parsing to use last instead of first @.
Browse files Browse the repository at this point in the history
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
  • Loading branch information
Adam Vartanian committed Nov 7, 2017
1 parent ca7ffa0 commit cd6228d
Show file tree
Hide file tree
Showing 2 changed files with 8 additions and 3 deletions.
6 changes: 3 additions & 3 deletions core/java/android/net/Uri.java
Original file line number Diff line number Diff line change
Expand Up @@ -1060,7 +1060,7 @@ private String parseUserInfo() {
return null;
}

int end = authority.indexOf('@');
int end = authority.lastIndexOf('@');
return end == NOT_FOUND ? null : authority.substring(0, end);
}

Expand All @@ -1084,7 +1084,7 @@ private String parseHost() {
}

// 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
Expand All @@ -1110,7 +1110,7 @@ private int parsePort() {

// 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) {
Expand Down
5 changes: 5 additions & 0 deletions core/tests/coretests/src/android/net/UriTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,11 @@ public void testAuthorityParsing() {
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
Expand Down

0 comments on commit cd6228d

Please sign in to comment.