URLParser: Handle \ in path according to spec
authorachristensen@apple.com <achristensen@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 9 Sep 2016 17:56:10 +0000 (17:56 +0000)
committerachristensen@apple.com <achristensen@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 9 Sep 2016 17:56:10 +0000 (17:56 +0000)
https://bugs.webkit.org/show_bug.cgi?id=161805

Reviewed by Andy Estes.

Source/WebCore:

Covered by new API tests.

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

Tools:

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

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@205752 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebCore/ChangeLog
Source/WebCore/platform/URLParser.cpp
Tools/ChangeLog
Tools/TestWebKitAPI/Tests/WebCore/URLParser.cpp

index 99a5390..8ffcdb1 100644 (file)
@@ -1,3 +1,15 @@
+2016-09-09  Alex Christensen  <achristensen@webkit.org>
+
+        URLParser: Handle \ in path according to spec
+        https://bugs.webkit.org/show_bug.cgi?id=161805
+
+        Reviewed by Andy Estes.
+
+        Covered by new API tests.
+
+        * platform/URLParser.cpp:
+        (WebCore::URLParser::parse):
+
 2016-09-09  Youenn Fablet  <youenn@apple.com>
 
         TextTrackLoader should use FetchOptions::mode according its crossOrigin attribute
index d811e81..6a3611a 100644 (file)
@@ -606,27 +606,31 @@ URL URLParser::parse(const String& input, const URL& base, const TextEncoding& e
             break;
         case State::AuthorityOrHost:
             LOG_STATE("AuthorityOrHost");
-            if (*c == '@') {
-                parseAuthority(authorityOrHostBegin, c);
-                ++c;
-                while (c != end && isTabOrNewline(*c))
+            {
+                if (*c == '@') {
+                    parseAuthority(authorityOrHostBegin, c);
                     ++c;
-                authorityOrHostBegin = c;
-                state = State::Host;
-                break;
-            } else if (*c == '/' || *c == '?' || *c == '#') {
-                m_url.m_userEnd = m_buffer.length();
-                m_url.m_passwordEnd = m_url.m_userEnd;
-                if (!parseHost(authorityOrHostBegin, c))
-                    return failure(input);
-                if (*c != '/') {
-                    m_buffer.append('/');
-                    m_url.m_pathAfterLastSlash = m_buffer.length();
+                    while (c != end && isTabOrNewline(*c))
+                        ++c;
+                    authorityOrHostBegin = c;
+                    state = State::Host;
+                    break;
                 }
-                state = State::Path;
-                break;
+                bool isSlash = *c == '/' || (m_urlIsSpecial && *c == '\\');
+                if (isSlash || *c == '?' || *c == '#') {
+                    m_url.m_userEnd = m_buffer.length();
+                    m_url.m_passwordEnd = m_url.m_userEnd;
+                    if (!parseHost(authorityOrHostBegin, c))
+                        return failure(input);
+                    if (!isSlash) {
+                        m_buffer.append('/');
+                        m_url.m_pathAfterLastSlash = m_buffer.length();
+                    }
+                    state = State::Path;
+                    break;
+                }
+                ++c;
             }
-            ++c;
             break;
         case State::Host:
             LOG_STATE("Host");
index 26e77b7..ffc5b15 100644 (file)
@@ -1,5 +1,15 @@
 2016-09-09  Alex Christensen  <achristensen@webkit.org>
 
+        URLParser: Handle \ in path according to spec
+        https://bugs.webkit.org/show_bug.cgi?id=161805
+
+        Reviewed by Andy Estes.
+
+        * TestWebKitAPI/Tests/WebCore/URLParser.cpp:
+        (TestWebKitAPI::TEST_F):
+
+2016-09-09  Alex Christensen  <achristensen@webkit.org>
+
         URLParser should parse URLs with non-special schemes
         https://bugs.webkit.org/show_bug.cgi?id=161786
 
index f8ab433..9fc062b 100644 (file)
@@ -263,6 +263,9 @@ TEST_F(URLParserTest, ParseRelative)
     checkRelativeURL(":foo.com\\", "http://example.org/foo/bar", {"http", "", "", "example.org", 0, "/foo/:foo.com/", "", "", "http://example.org/foo/:foo.com/"});
     checkRelativeURL("http:/example.com/", "about:blank", {"http", "", "", "example.com", 0, "/", "", "", "http://example.com/"});
     checkRelativeURL("http:example.com/", "about:blank", {"http", "", "", "example.com", 0, "/", "", "", "http://example.com/"});
+    checkRelativeURL("http:\\\\foo.com\\", "http://example.org/foo/bar", {"http", "", "", "foo.com", 0, "/", "", "", "http://foo.com/"});
+    checkRelativeURL("http:\\\\foo.com/", "http://example.org/foo/bar", {"http", "", "", "foo.com", 0, "/", "", "", "http://foo.com/"});
+    checkRelativeURL("http:\\\\foo.com", "http://example.org/foo/bar", {"http", "", "", "foo.com", 0, "/", "", "", "http://foo.com/"});
 }
 
 static void checkURLDifferences(const String& urlString, const ExpectedParts& partsNew, const ExpectedParts& partsOld)
@@ -411,7 +414,15 @@ TEST_F(URLParserTest, ParserDifferences)
     checkURLDifferences("sc://pa",
         {"sc", "", "", "pa", 0, "/", "", "", "sc://pa/"},
         {"sc", "", "", "pa", 0, "", "", "", "sc://pa"});
-
+    checkRelativeURLDifferences("notspecial:\\\\foo.com\\", "http://example.org/foo/bar",
+        {"notspecial", "", "", "", 0, "\\\\foo.com\\", "", "", "notspecial:\\\\foo.com\\"},
+        {"notspecial", "", "", "foo.com", 0, "/", "", "", "notspecial://foo.com/"});
+    checkRelativeURLDifferences("notspecial:\\\\foo.com/", "http://example.org/foo/bar",
+        {"notspecial", "", "", "", 0, "\\\\foo.com/", "", "", "notspecial:\\\\foo.com/"},
+        {"notspecial", "", "", "foo.com", 0, "/", "", "", "notspecial://foo.com/"});
+    checkRelativeURLDifferences("notspecial:\\\\foo.com", "http://example.org/foo/bar",
+        {"notspecial", "", "", "", 0, "\\\\foo.com", "", "", "notspecial:\\\\foo.com"},
+        {"notspecial", "", "", "foo.com", 0, "", "", "", "notspecial://foo.com"});
     
     // This behavior matches Chrome and Firefox, but not WebKit using URL::parse.
     // The behavior of URL::parse is clearly wrong because reparsing file://path would make path the host.