summaryrefslogtreecommitdiff
path: root/core/java/android
diff options
context:
space:
mode:
authorChalard Jean <jchalard@google.com>2018-10-19 05:10:55 -0700
committerandroid-build-merger <android-build-merger@google.com>2018-10-19 05:10:55 -0700
commit86ff3f4c7aabafadedd35c5dca368a50f936bb3b (patch)
treedf350489a3d34a091b4ddb1f7c486b197c0967b8 /core/java/android
parent96cb6d97e122562660b4d0be190abb5ea7ab120c (diff)
parent54677a86d45abe237b6726c22c52162fd2dacbcd (diff)
Merge "Fix a bug where Uri can't parse IPv6 literal addresses."
am: 54677a86d4 Change-Id: Ibf681262344904990f77f9016f3ffc9efbce08ba
Diffstat (limited to 'core/java/android')
-rw-r--r--core/java/android/net/Uri.java37
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;
+ }
}
/**