Adjust URI host parsing to stop on \ character.

The WHATWG URL parsing algorithm [1] used by browsers says that for
"special" URL schemes (which is basically all commonly-used
hierarchical schemes, including http, https, ftp, and file), the host
portion ends if a \ character is seen, whereas this class previously
continued to consider characters part of the hostname.  This meant
that a malicious URL could be seen as having a "safe" host when viewed
by an app but navigate to a different host when passed to a browser.

[1] https://url.spec.whatwg.org/#host-state

Bug: 71360761
Test: vogar frameworks/base/core/tests/coretests/src/android/net/UriTest.java (on NYC branch)
Test: cts -m CtsNetTestCases (on NYC branch)
Change-Id: Id53f7054d1be8d59bbcc7e219159e59a2425106e
(cherry picked from commit fa3afbd0e7a9a0d8fc8c55ceefdb4ddf9d0115af)
diff --git a/core/java/android/net/Uri.java b/core/java/android/net/Uri.java
index 9edcc0e..5ca3a41 100644
--- a/core/java/android/net/Uri.java
+++ b/core/java/android/net/Uri.java
@@ -720,6 +720,10 @@
                 LOOP: while (end < length) {
                     switch (uriString.charAt(end)) {
                         case '/': // Start of path
+                        case '\\':// Start of path
+                          // Per http://url.spec.whatwg.org/#host-state, the \ character
+                          // is treated as if it were a / character when encountered in a
+                          // host
                         case '?': // Start of query
                         case '#': // Start of fragment
                             break LOOP;
@@ -758,6 +762,10 @@
                         case '#': // Start of fragment
                             return ""; // Empty path.
                         case '/': // Start of path!
+                        case '\\':// Start of path!
+                          // Per http://url.spec.whatwg.org/#host-state, the \ character
+                          // is treated as if it were a / character when encountered in a
+                          // host
                             break LOOP;
                     }
                     pathStart++;
diff --git a/core/tests/coretests/src/android/net/UriTest.java b/core/tests/coretests/src/android/net/UriTest.java
index 27b7f9e..ea0347d 100644
--- a/core/tests/coretests/src/android/net/UriTest.java
+++ b/core/tests/coretests/src/android/net/UriTest.java
@@ -192,6 +192,12 @@
         assertEquals("a:a@example.com:a@example2.com", uri.getAuthority());
         assertEquals("example2.com", uri.getHost());
         assertEquals(-1, uri.getPort());
+        assertEquals("/path", uri.getPath());
+
+        uri = Uri.parse("http://a.foo.com\\.example.com/path");
+        assertEquals("a.foo.com", uri.getHost());
+        assertEquals(-1, uri.getPort());
+        assertEquals("\\.example.com/path", uri.getPath());
     }
 
     @SmallTest