Title: [206783] trunk
Revision
206783
Author
[email protected]
Date
2016-10-04 14:20:54 -0700 (Tue, 04 Oct 2016)

Log Message

URLParser should match URL::parse and other browsers when parsing a URL containing only scheme://
https://bugs.webkit.org/show_bug.cgi?id=162909

Reviewed by Tim Horton.

Source/WebCore:

If there's no host in this case we shouldn't fail, but rather make a valid URL with the // in the path.
This matches Chrome, Firefox, and Safari's behavior.
Covered by API tests.

* platform/URLParser.cpp:
(WebCore::URLParser::parse):

Tools:

* TestWebKitAPI/Tests/WebCore/URLParser.cpp:
(TestWebKitAPI::TEST_F):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (206782 => 206783)


--- trunk/Source/WebCore/ChangeLog	2016-10-04 21:13:18 UTC (rev 206782)
+++ trunk/Source/WebCore/ChangeLog	2016-10-04 21:20:54 UTC (rev 206783)
@@ -1,3 +1,17 @@
+2016-10-04  Alex Christensen  <[email protected]>
+
+        URLParser should match URL::parse and other browsers when parsing a URL containing only scheme://
+        https://bugs.webkit.org/show_bug.cgi?id=162909
+
+        Reviewed by Tim Horton.
+
+        If there's no host in this case we shouldn't fail, but rather make a valid URL with the // in the path.
+        This matches Chrome, Firefox, and Safari's behavior.
+        Covered by API tests.
+
+        * platform/URLParser.cpp:
+        (WebCore::URLParser::parse):
+
 2016-10-04  Brent Fulgham  <[email protected]>
 
         Unreviewed build fix after r206773.

Modified: trunk/Source/WebCore/platform/URLParser.cpp (206782 => 206783)


--- trunk/Source/WebCore/platform/URLParser.cpp	2016-10-04 21:13:18 UTC (rev 206782)
+++ trunk/Source/WebCore/platform/URLParser.cpp	2016-10-04 21:20:54 UTC (rev 206783)
@@ -1400,17 +1400,32 @@
                 }
                 bool isSlash = *c == '/' || (m_urlIsSpecial && *c == '\\');
                 if (isSlash || *c == '?' || *c == '#') {
-                    m_url.m_userEnd = currentPosition(authorityOrHostBegin);
-                    m_url.m_passwordEnd = m_url.m_userEnd;
-                    if (!parseHostAndPort(CodePointIterator<CharacterType>(authorityOrHostBegin, c))) {
-                        failure();
-                        return;
+                    auto iterator = CodePointIterator<CharacterType>(authorityOrHostBegin, c);
+                    if (iterator.atEnd()) {
+                        size_t position = currentPosition(c);
+                        ASSERT(m_url.m_userStart == position);
+                        RELEASE_ASSERT(position >= 2);
+                        position -= 2;
+                        ASSERT(parsedDataView(position, 2) == "//");
+                        m_url.m_userStart = position;
+                        m_url.m_userEnd = position;
+                        m_url.m_passwordEnd = position;
+                        m_url.m_hostEnd = position;
+                        m_url.m_portEnd = position;
+                        m_url.m_pathAfterLastSlash = position + 2;
+                    } else {
+                        m_url.m_userEnd = currentPosition(authorityOrHostBegin);
+                        m_url.m_passwordEnd = m_url.m_userEnd;
+                        if (!parseHostAndPort(iterator)) {
+                            failure();
+                            return;
+                        }
+                        if (UNLIKELY(!isSlash)) {
+                            syntaxViolation(c);
+                            appendToASCIIBuffer('/');
+                            m_url.m_pathAfterLastSlash = currentPosition(c);
+                        }
                     }
-                    if (UNLIKELY(!isSlash)) {
-                        syntaxViolation(c);
-                        appendToASCIIBuffer('/');
-                        m_url.m_pathAfterLastSlash = currentPosition(c);
-                    }
                     state = State::Path;
                     break;
                 }
@@ -1818,15 +1833,22 @@
         m_url.m_userEnd = currentPosition(authorityOrHostBegin);
         m_url.m_passwordEnd = m_url.m_userEnd;
         if (authorityOrHostBegin.atEnd()) {
-            m_url.m_hostEnd = m_url.m_userEnd;
-            m_url.m_portEnd = m_url.m_userEnd;
+            RELEASE_ASSERT(m_url.m_userStart >= 2);
+            ASSERT(parsedDataView(m_url.m_userStart - 2, 2) == "//");
+            m_url.m_userStart -= 2;
+            m_url.m_userEnd = m_url.m_userStart;
+            m_url.m_passwordEnd = m_url.m_userStart;
+            m_url.m_hostEnd = m_url.m_userStart;
+            m_url.m_portEnd = m_url.m_userStart;
+            m_url.m_pathEnd = m_url.m_userStart + 2;
         } else if (!parseHostAndPort(authorityOrHostBegin)) {
             failure();
             return;
+        } else {
+            syntaxViolation(c);
+            appendToASCIIBuffer('/');
+            m_url.m_pathEnd = m_url.m_portEnd + 1;
         }
-        syntaxViolation(c);
-        appendToASCIIBuffer('/');
-        m_url.m_pathEnd = m_url.m_portEnd + 1;
         m_url.m_pathAfterLastSlash = m_url.m_pathEnd;
         m_url.m_queryEnd = m_url.m_pathEnd;
         m_url.m_fragmentEnd = m_url.m_pathEnd;

Modified: trunk/Tools/ChangeLog (206782 => 206783)


--- trunk/Tools/ChangeLog	2016-10-04 21:13:18 UTC (rev 206782)
+++ trunk/Tools/ChangeLog	2016-10-04 21:20:54 UTC (rev 206783)
@@ -1,3 +1,13 @@
+2016-10-04  Alex Christensen  <[email protected]>
+
+        URLParser should match URL::parse and other browsers when parsing a URL containing only scheme://
+        https://bugs.webkit.org/show_bug.cgi?id=162909
+
+        Reviewed by Tim Horton.
+
+        * TestWebKitAPI/Tests/WebCore/URLParser.cpp:
+        (TestWebKitAPI::TEST_F):
+
 2016-10-04  Yusuke Suzuki  <[email protected]>
 
         [DOMJIT] Introduce DOMJIT::GetterSetter to tell JIT information

Modified: trunk/Tools/TestWebKitAPI/Tests/WebCore/URLParser.cpp (206782 => 206783)


--- trunk/Tools/TestWebKitAPI/Tests/WebCore/URLParser.cpp	2016-10-04 21:13:18 UTC (rev 206782)
+++ trunk/Tools/TestWebKitAPI/Tests/WebCore/URLParser.cpp	2016-10-04 21:20:54 UTC (rev 206783)
@@ -314,6 +314,20 @@
     checkURL("http://host:123?query", {"http", "", "", "host", 123, "/", "query", "", "http://host:123/?query"});
     checkURL("http://host:123#", {"http", "", "", "host", 123, "/", "", "", "http://host:123/#"});
     checkURL("http://host:123#fragment", {"http", "", "", "host", 123, "/", "", "fragment", "http://host:123/#fragment"});
+    checkURL("foo:////", {"foo", "", "", "", 0, "////", "", "", "foo:////"});
+    checkURL("foo:///?", {"foo", "", "", "", 0, "///", "", "", "foo:///?"});
+    checkURL("foo:///#", {"foo", "", "", "", 0, "///", "", "", "foo:///#"});
+    checkURL("foo:///", {"foo", "", "", "", 0, "///", "", "", "foo:///"});
+    checkURL("foo://?", {"foo", "", "", "", 0, "//", "", "", "foo://?"});
+    checkURL("foo://#", {"foo", "", "", "", 0, "//", "", "", "foo://#"});
+    checkURL("foo://", {"foo", "", "", "", 0, "//", "", "", "foo://"});
+    checkURL("foo:/?", {"foo", "", "", "", 0, "/", "", "", "foo:/?"});
+    checkURL("foo:/#", {"foo", "", "", "", 0, "/", "", "", "foo:/#"});
+    checkURL("foo:/", {"foo", "", "", "", 0, "/", "", "", "foo:/"});
+    checkURL("foo:?", {"foo", "", "", "", 0, "", "", "", "foo:?"});
+    checkURL("foo:#", {"foo", "", "", "", 0, "", "", "", "foo:#"});
+    checkURL("A://", {"a", "", "", "", 0, "//", "", "", "a://"});
+    checkURL("aA://", {"aa", "", "", "", 0, "//", "", "", "aa://"});
 
     // This disagrees with the web platform test for http://:@www.example.com but agrees with Chrome and URL::parse,
     // and Firefox fails the web platform test differently. Maybe the web platform test ought to be changed.
@@ -433,6 +447,7 @@
     checkRelativeURL("  ", "http://host/#fragment", {"http", "", "", "host", 0, "/", "", "", "http://host/"});
     checkRelativeURL("  ", "http://host/path?query#fra#gment", {"http", "", "", "host", 0, "/path", "query", "", "http://host/path?query"});
     checkRelativeURL(" \a ", "http://host/#fragment", {"http", "", "", "host", 0, "/", "", "", "http://host/"});
+    checkRelativeURL("foo://", "http://example.org/foo/bar", {"foo", "", "", "", 0, "//", "", "", "foo://"});
 
     // The checking of slashes in SpecialAuthoritySlashes needed to get this to pass contradicts what is in the spec,
     // but it is included in the web platform tests.
@@ -729,9 +744,6 @@
     checkURLDifferences("notspecial://@test@test@example:800\\path@end",
         {"notspecial", "@test@test@example", "800\\path", "end", 0, "/", "", "", "notspecial://%40test%40test%40example:800%5Cpath@end/"},
         {"", "", "", "", 0, "", "", "", "notspecial://@test@test@example:800\\path@end"});
-    checkRelativeURLDifferences("foo://", "http://example.org/foo/bar",
-        {"foo", "", "", "", 0, "/", "", "", "foo:///"},
-        {"foo", "", "", "", 0, "//", "", "", "foo://"});
     checkURLDifferences(utf16String(u"http://host?ß😍#ß😍"),
         {"http", "", "", "host", 0, "/", "%C3%9F%F0%9F%98%8D", utf16String(u"ß😍"), utf16String(u"http://host/?%C3%9F%F0%9F%98%8D#ß😍")},
         {"http", "", "", "host", 0, "/", "%C3%9F%F0%9F%98%8D", "%C3%9F%F0%9F%98%8D", "http://host/?%C3%9F%F0%9F%98%8D#%C3%9F%F0%9F%98%8D"}, testTabsValueForSurrogatePairs);
@@ -753,12 +765,6 @@
     checkURLDifferences("http://host/`",
         {"http", "", "", "host", 0, "/%60", "", "", "http://host/%60"},
         {"http", "", "", "host", 0, "/`", "", "", "http://host/`"});
-    checkURLDifferences("aA://",
-        {"aa", "", "", "", 0, "/", "", "", "aa:///"},
-        {"aa", "", "", "", 0, "//", "", "", "aa://"});
-    checkURLDifferences("A://",
-        {"a", "", "", "", 0, "/", "", "", "a:///"},
-        {"a", "", "", "", 0, "//", "", "", "a://"});
     checkURLDifferences("http://://",
         {"", "", "", "", 0, "", "", "", "http://://"},
         {"http", "", "", "", 0, "//", "", "", "http://://"});
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to