Merge cherrypicks of [4741663, 4741664, 4741665, 4741666, 4743080, 4743081, 4743082, 4743083, 4741262, 4741263, 4741264, 4741265, 4741266, 4741667, 4743084, 4741242, 4741243, 4741741, 4741742, 4741743, 4741744, 4741822, 4743085, 4741668, 4741338, 4743055, 4743056, 4743070, 4743073, 4743075, 4743076, 4743078, 4743079, 4743161, 4743162, 4743164, 4743165, 4743167, 4743168, 4743169, 4743170, 4741681, 4741682, 4741683, 4741684, 4741685, 4741686, 4741687, 4741688, 4741689, 4741690, 4741691, 4741692, 4741693, 4741694, 4741695, 4741696, 4741697, 4741698, 4741699, 4743240, 4743241, 4743242, 4743243, 4741745, 4741823, 4741824, 4741825, 4741267, 4741268, 4743244, 4743280, 4743281, 4743224, 4743203, 4743204, 4743205, 4741746, 4741747, 4743245, 4741826, 4741827, 4741828, 4741829, 4741748, 4741749, 4741750, 4743233, 4743282, 4741244, 4741245, 4741246, 4741247, 4743206, 4743207, 4743208, 4743209, 4743210, 4743211, 4743212, 4743213, 4743214, 4743215, 4743216, 4743217, 4743218, 4743219, 4743360, 4743361, 4743362, 4743363, 4743364, 4743365, 4743366, 4743367, 4743368, 4743369, 4743370, 4743371, 4743372, 4743373, 4743374, 4743375, 4743376, 4743377, 4743283, 4743284, 4741830, 4742501, 4743246, 4743086, 4743087, 4743378, 4743379, 4741751] into sparse-4749909-L04200000199131547

Change-Id: I7633832ee105f3cbd484b61a7b13f12ac9ca904f
diff --git a/luni/src/test/java/libcore/java/net/URLTest.java b/luni/src/test/java/libcore/java/net/URLTest.java
index 231e09c..58bd8cc 100644
--- a/luni/src/test/java/libcore/java/net/URLTest.java
+++ b/luni/src/test/java/libcore/java/net/URLTest.java
@@ -409,6 +409,26 @@
         assertEquals("http://host/a/c", url.toString()); // RI doesn't canonicalize
     }
 
+    public void testPathContainsBackslash() throws Exception {
+        URL url = new URL("http://host\\path@foo");
+        assertEquals("\\path@foo", url.getPath());
+        assertEquals("host", url.getHost());
+    }
+
+    public void testQueryContainsForwardSlash() throws Exception {
+        URL url = new URL("http://host?query/foo");
+        assertEquals("", url.getPath());
+        assertEquals("host", url.getHost());
+        assertEquals("query/foo", url.getQuery());
+    }
+
+    public void testFragmentContainsForwardSlash() throws Exception {
+        URL url = new URL("http://host#fragment/foo");
+        assertEquals("", url.getPath());
+        assertEquals("host", url.getHost());
+        assertEquals("fragment/foo", url.getRef());
+    }
+
     public void testRelativePathAndFragment() throws Exception {
         URL base = new URL("http://host/file");
         assertEquals("http://host/another#fragment", new URL(base, "another#fragment").toString());
diff --git a/ojluni/src/main/java/java/net/URLStreamHandler.java b/ojluni/src/main/java/java/net/URLStreamHandler.java
index eac8a78..ad25dfc 100644
--- a/ojluni/src/main/java/java/net/URLStreamHandler.java
+++ b/ojluni/src/main/java/java/net/URLStreamHandler.java
@@ -167,12 +167,25 @@
         if (!isUNCName && (start <= limit - 2) && (spec.charAt(start) == '/') &&
             (spec.charAt(start + 1) == '/')) {
             start += 2;
+            // BEGIN Android-changed: Check for all hostname termination chars. http://b/110955991
+            /*
             i = spec.indexOf('/', start);
             if (i < 0 || i > limit) {
                 i = spec.indexOf('?', start);
                 if (i < 0 || i > limit)
                     i = limit;
             }
+            */
+            LOOP: for (i = start; i < limit; i++) {
+                switch (spec.charAt(i)) {
+                    case '/':  // Start of path
+                    case '\\': // Start of path - see https://url.spec.whatwg.org/#host-state
+                    case '?':  // Start of query
+                    case '#':  // Start of fragment
+                        break LOOP;
+                }
+            }
+            // END Android-changed: Check for all hostname termination chars. http://b/110955991
 
             host = authority = spec.substring(start, i);
 
@@ -266,7 +279,9 @@
 
         // Parse the file path if any
         if (start < limit) {
-            if (spec.charAt(start) == '/') {
+            // Android-changed: Check for all hostname termination chars. http://b/110955991
+            // if (spec.charAt(start) == '/') {
+            if (spec.charAt(start) == '/' || spec.charAt(start) == '\\') {
                 path = spec.substring(start, limit);
             } else if (path != null && path.length() > 0) {
                 isRelPath = true;