diff options
| author | 2018-10-19 06:28:37 -0700 | |
|---|---|---|
| committer | 2018-10-19 06:28:37 -0700 | |
| commit | 03eb7e1905918da7fa763691780b7071caefe8d4 (patch) | |
| tree | 436ddbb6ae1ac63c78c83cd4799aff178bd1f6b0 | |
| parent | 1ce954ceb1192711ddba46470c12ed5778f67c33 (diff) | |
| parent | 6997192f3524ef363d8ea7173b14fa03c2aa8e02 (diff) | |
Merge "Fix a bug where Uri can't parse IPv6 literal addresses." am: 54677a86d4 am: 86ff3f4c7a
am: 6997192f35
Change-Id: I591c592e64a48f71f5528d999426343977fe48ce
| -rw-r--r-- | core/java/android/net/Uri.java | 37 |
1 files changed, 23 insertions, 14 deletions
diff --git a/core/java/android/net/Uri.java b/core/java/android/net/Uri.java index 40465ceafcb8..d09f33bcb755 100644 --- a/core/java/android/net/Uri.java +++ b/core/java/android/net/Uri.java @@ -1102,19 +1102,18 @@ public abstract class Uri implements Parcelable, Comparable<Uri> { public String getHost() { @SuppressWarnings("StringEquality") boolean cached = (host != NOT_CACHED); - return cached ? host - : (host = parseHost()); + return cached ? host : (host = parseHost()); } private String parseHost() { - String authority = getEncodedAuthority(); + final String authority = getEncodedAuthority(); if (authority == null) { return null; } // Parse out user info and then port. int userInfoSeparator = authority.lastIndexOf('@'); - int portSeparator = authority.indexOf(':', userInfoSeparator); + int portSeparator = findPortSeparator(authority); String encodedHost = portSeparator == NOT_FOUND ? authority.substring(userInfoSeparator + 1) @@ -1132,16 +1131,8 @@ public abstract class Uri implements Parcelable, Comparable<Uri> { } private int parsePort() { - String authority = getEncodedAuthority(); - if (authority == null) { - return -1; - } - - // 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.lastIndexOf('@'); - int portSeparator = authority.indexOf(':', userInfoSeparator); - + final String authority = getEncodedAuthority(); + int portSeparator = findPortSeparator(authority); if (portSeparator == NOT_FOUND) { return -1; } @@ -1154,6 +1145,24 @@ public abstract class Uri implements Parcelable, Comparable<Uri> { return -1; } } + + private int findPortSeparator(String authority) { + if (authority == null) { + return NOT_FOUND; + } + + // Reverse search for the ':' character that breaks as soon as a char that is neither + // a colon nor an ascii digit is encountered. Thanks to the goodness of UTF-16 encoding, + // it's not possible that a surrogate matches one of these, so this loop can just + // look for characters rather than care about code points. + for (int i = authority.length() - 1; i >= 0; --i) { + final int character = authority.charAt(i); + if (':' == character) return i; + // Character.isDigit would include non-ascii digits + if (character < '0' || character > '9') return NOT_FOUND; + } + return NOT_FOUND; + } } /** |