frameworks/base
Revision | 51e18dfdaf45f1583bff18e69b73c0991049fc20 (tree) |
---|---|
Time | 2018-01-16 23:24:54 |
Author | Adam Vartanian <flooey@goog...> |
Commiter | Bruno Martins |
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
Bug: 68341964
Test: vogar android.net.UriTest (on NYC branch)
Test: cts -m CtsNetTestCases (on NYC branch)
Change-Id: Idca79f35a886de042c94d6ab66787c2e98ac8376
(cherry picked from commit cd6228dd377b2a0caa02a1e6df92f3d9ae702a95)
@@ -1065,7 +1065,7 @@ public abstract class Uri implements Parcelable, Comparable<Uri> { | ||
1065 | 1065 | return null; |
1066 | 1066 | } |
1067 | 1067 | |
1068 | - int end = authority.indexOf('@'); | |
1068 | + int end = authority.lastIndexOf('@'); | |
1069 | 1069 | return end == NOT_FOUND ? null : authority.substring(0, end); |
1070 | 1070 | } |
1071 | 1071 |
@@ -1089,7 +1089,7 @@ public abstract class Uri implements Parcelable, Comparable<Uri> { | ||
1089 | 1089 | } |
1090 | 1090 | |
1091 | 1091 | // Parse out user info and then port. |
1092 | - int userInfoSeparator = authority.indexOf('@'); | |
1092 | + int userInfoSeparator = authority.lastIndexOf('@'); | |
1093 | 1093 | int portSeparator = authority.indexOf(':', userInfoSeparator); |
1094 | 1094 | |
1095 | 1095 | String encodedHost = portSeparator == NOT_FOUND |
@@ -1115,7 +1115,7 @@ public abstract class Uri implements Parcelable, Comparable<Uri> { | ||
1115 | 1115 | |
1116 | 1116 | // Make sure we look for the port separtor *after* the user info |
1117 | 1117 | // separator. We have URLs with a ':' in the user info. |
1118 | - int userInfoSeparator = authority.indexOf('@'); | |
1118 | + int userInfoSeparator = authority.lastIndexOf('@'); | |
1119 | 1119 | int portSeparator = authority.indexOf(':', userInfoSeparator); |
1120 | 1120 | |
1121 | 1121 | if (portSeparator == NOT_FOUND) { |
@@ -187,6 +187,11 @@ public class UriTest extends TestCase { | ||
187 | 187 | uri = Uri.parse("http://localhost"); |
188 | 188 | assertEquals("localhost", uri.getHost()); |
189 | 189 | assertEquals(-1, uri.getPort()); |
190 | + | |
191 | + uri = Uri.parse("http://a:a@example.com:a@example2.com/path"); | |
192 | + assertEquals("a:a@example.com:a@example2.com", uri.getAuthority()); | |
193 | + assertEquals("example2.com", uri.getHost()); | |
194 | + assertEquals(-1, uri.getPort()); | |
190 | 195 | } |
191 | 196 | |
192 | 197 | @SmallTest |