diff --git a/LayoutTests/imported/w3c/ChangeLog b/LayoutTests/imported/w3c/ChangeLog index 787554e66abef..4afd8d49d9c9b 100644 --- a/LayoutTests/imported/w3c/ChangeLog +++ b/LayoutTests/imported/w3c/ChangeLog @@ -1,3 +1,15 @@ +2020-10-02 Alex Christensen + + Copy host from base file URL + https://bugs.webkit.org/show_bug.cgi?id=217170 + + Reviewed by Brady Eidson. + + * web-platform-tests/url/a-element-expected.txt: + * web-platform-tests/url/a-element-xhtml-expected.txt: + * web-platform-tests/url/resources/urltestdata.json: + * web-platform-tests/url/url-constructor-expected.txt: + 2020-10-02 Sam Weinig Re-align HTMLElement with the HTML spec diff --git a/LayoutTests/imported/w3c/web-platform-tests/url/a-element-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/url/a-element-expected.txt index 38411ef39d1d3..feb1889745862 100644 --- a/LayoutTests/imported/w3c/web-platform-tests/url/a-element-expected.txt +++ b/LayoutTests/imported/w3c/web-platform-tests/url/a-element-expected.txt @@ -417,6 +417,8 @@ PASS Parsing: against against PASS Parsing: <..> against PASS Parsing: against +PASS Parsing: against +PASS Parsing: against PASS Parsing: against PASS Parsing: against PASS Parsing: <..> against @@ -427,24 +429,24 @@ PASS Parsing: against PASS Parsing: against PASS Parsing: <#x> against PASS Parsing: against -FAIL Parsing: against assert_equals: href expected "file:///" but got "file:////" -FAIL Parsing: against assert_equals: href expected "file:///" but got "file:////" -FAIL Parsing: against assert_equals: href expected "file:///?fox" but got "file:////?fox" -FAIL Parsing: against assert_equals: href expected "file:///#guppy" but got "file:////#guppy" -FAIL Parsing: against assert_equals: href expected "file://spider/" but got "file://spider///" -FAIL Parsing: against assert_equals: href expected "file:///" but got "file:////" +PASS Parsing: against +PASS Parsing: against +PASS Parsing: against +PASS Parsing: against +PASS Parsing: against +PASS Parsing: against PASS Parsing: against -FAIL Parsing: against assert_equals: href expected "file:///localhost//cat" but got "file:////localhost//cat" -FAIL Parsing: against assert_equals: href expected "file:///" but got "file://///" -FAIL Parsing: against assert_equals: href expected "file:///mouse" but got "file://///mouse" +PASS Parsing: against +PASS Parsing: against +PASS Parsing: against PASS Parsing: <\//pig> against -FAIL Parsing: <\/localhost//pig> against assert_equals: href expected "file:///pig" but got "file:////pig" -FAIL Parsing: against assert_equals: href expected "file:///pig" but got "file:////pig" -FAIL Parsing: against assert_equals: href expected "file://lion/localhost//pig" but got "file:////localhost//pig" +PASS Parsing: <\/localhost//pig> against +PASS Parsing: against +PASS Parsing: against PASS Parsing: against -FAIL Parsing: against assert_equals: href expected "file://tea/rooibos" but got "file:///rooibos" -FAIL Parsing: against assert_equals: href expected "file://tea/?chai" but got "file:///?chai" -FAIL Parsing: against assert_equals: href expected "file:///C:" but got "file://host/dir/C|" +PASS Parsing: against +PASS Parsing: against +FAIL Parsing: against assert_equals: href expected "file://host/C:" but got "file://host/dir/C|" PASS Parsing: against PASS Parsing: against PASS Parsing: against @@ -457,9 +459,9 @@ PASS Parsing: against PASS Parsing: against PASS Parsing: against PASS Parsing: against -FAIL Parsing: against assert_equals: href expected "file:///C:/" but got "file://example.net/C:/" -FAIL Parsing: against assert_equals: href expected "file:///C:/" but got "file://1.2.3.4/C:/" -FAIL Parsing: against assert_equals: href expected "file:///C:/" but got "file://[1::8]/C:/" +PASS Parsing: against +PASS Parsing: against +PASS Parsing: against PASS Parsing: against PASS Parsing: against PASS Parsing: against @@ -475,6 +477,15 @@ PASS Parsing: against PASS Parsing: against PASS Parsing: against PASS Parsing: <\\\.\y:> against +PASS Parsing: against +PASS Parsing: against +PASS Parsing: against +PASS Parsing: against +PASS Parsing: against +PASS Parsing: against +PASS Parsing: against +PASS Parsing: against +PASS Parsing: against PASS Parsing: against PASS Parsing: against PASS Parsing: against diff --git a/LayoutTests/imported/w3c/web-platform-tests/url/a-element-xhtml-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/url/a-element-xhtml-expected.txt index 38411ef39d1d3..feb1889745862 100644 --- a/LayoutTests/imported/w3c/web-platform-tests/url/a-element-xhtml-expected.txt +++ b/LayoutTests/imported/w3c/web-platform-tests/url/a-element-xhtml-expected.txt @@ -417,6 +417,8 @@ PASS Parsing: against against PASS Parsing: <..> against PASS Parsing: against +PASS Parsing: against +PASS Parsing: against PASS Parsing: against PASS Parsing: against PASS Parsing: <..> against @@ -427,24 +429,24 @@ PASS Parsing: against PASS Parsing: against PASS Parsing: <#x> against PASS Parsing: against -FAIL Parsing: against assert_equals: href expected "file:///" but got "file:////" -FAIL Parsing: against assert_equals: href expected "file:///" but got "file:////" -FAIL Parsing: against assert_equals: href expected "file:///?fox" but got "file:////?fox" -FAIL Parsing: against assert_equals: href expected "file:///#guppy" but got "file:////#guppy" -FAIL Parsing: against assert_equals: href expected "file://spider/" but got "file://spider///" -FAIL Parsing: against assert_equals: href expected "file:///" but got "file:////" +PASS Parsing: against +PASS Parsing: against +PASS Parsing: against +PASS Parsing: against +PASS Parsing: against +PASS Parsing: against PASS Parsing: against -FAIL Parsing: against assert_equals: href expected "file:///localhost//cat" but got "file:////localhost//cat" -FAIL Parsing: against assert_equals: href expected "file:///" but got "file://///" -FAIL Parsing: against assert_equals: href expected "file:///mouse" but got "file://///mouse" +PASS Parsing: against +PASS Parsing: against +PASS Parsing: against PASS Parsing: <\//pig> against -FAIL Parsing: <\/localhost//pig> against assert_equals: href expected "file:///pig" but got "file:////pig" -FAIL Parsing: against assert_equals: href expected "file:///pig" but got "file:////pig" -FAIL Parsing: against assert_equals: href expected "file://lion/localhost//pig" but got "file:////localhost//pig" +PASS Parsing: <\/localhost//pig> against +PASS Parsing: against +PASS Parsing: against PASS Parsing: against -FAIL Parsing: against assert_equals: href expected "file://tea/rooibos" but got "file:///rooibos" -FAIL Parsing: against assert_equals: href expected "file://tea/?chai" but got "file:///?chai" -FAIL Parsing: against assert_equals: href expected "file:///C:" but got "file://host/dir/C|" +PASS Parsing: against +PASS Parsing: against +FAIL Parsing: against assert_equals: href expected "file://host/C:" but got "file://host/dir/C|" PASS Parsing: against PASS Parsing: against PASS Parsing: against @@ -457,9 +459,9 @@ PASS Parsing: against PASS Parsing: against PASS Parsing: against PASS Parsing: against -FAIL Parsing: against assert_equals: href expected "file:///C:/" but got "file://example.net/C:/" -FAIL Parsing: against assert_equals: href expected "file:///C:/" but got "file://1.2.3.4/C:/" -FAIL Parsing: against assert_equals: href expected "file:///C:/" but got "file://[1::8]/C:/" +PASS Parsing: against +PASS Parsing: against +PASS Parsing: against PASS Parsing: against PASS Parsing: against PASS Parsing: against @@ -475,6 +477,15 @@ PASS Parsing: against PASS Parsing: against PASS Parsing: against PASS Parsing: <\\\.\y:> against +PASS Parsing: against +PASS Parsing: against +PASS Parsing: against +PASS Parsing: against +PASS Parsing: against +PASS Parsing: against +PASS Parsing: against +PASS Parsing: against +PASS Parsing: against PASS Parsing: against PASS Parsing: against PASS Parsing: against diff --git a/LayoutTests/imported/w3c/web-platform-tests/url/resources/urltestdata.json b/LayoutTests/imported/w3c/web-platform-tests/url/resources/urltestdata.json index c7f7a9ed9d0b9..17ec849526e31 100644 --- a/LayoutTests/imported/w3c/web-platform-tests/url/resources/urltestdata.json +++ b/LayoutTests/imported/w3c/web-platform-tests/url/resources/urltestdata.json @@ -5245,6 +5245,34 @@ "search": "", "hash": "" }, + { + "input": "/", + "base": "file://h/C:/a/b", + "href": "file://h/C:/", + "protocol": "file:", + "username": "", + "password": "", + "host": "h", + "hostname": "h", + "port": "", + "pathname": "/C:/", + "search": "", + "hash": "" + }, + { + "input": "/", + "base": "file://h/a/b", + "href": "file://h/", + "protocol": "file:", + "username": "", + "password": "", + "host": "h", + "hostname": "h", + "port": "", + "pathname": "/", + "search": "", + "hash": "" + }, { "input": "//d:", "base": "file:///C:/a/b", @@ -5389,84 +5417,84 @@ { "input": "file:\\\\//", "base": "about:blank", - "href": "file:///", + "href": "file:////", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", - "pathname": "/", + "pathname": "//", "search": "", "hash": "" }, { "input": "file:\\\\\\\\", "base": "about:blank", - "href": "file:///", + "href": "file:////", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", - "pathname": "/", + "pathname": "//", "search": "", "hash": "" }, { "input": "file:\\\\\\\\?fox", "base": "about:blank", - "href": "file:///?fox", + "href": "file:////?fox", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", - "pathname": "/", + "pathname": "//", "search": "?fox", "hash": "" }, { "input": "file:\\\\\\\\#guppy", "base": "about:blank", - "href": "file:///#guppy", + "href": "file:////#guppy", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", - "pathname": "/", + "pathname": "//", "search": "", "hash": "#guppy" }, { "input": "file://spider///", "base": "about:blank", - "href": "file://spider/", + "href": "file://spider///", "protocol": "file:", "username": "", "password": "", "host": "spider", "hostname": "spider", "port": "", - "pathname": "/", + "pathname": "///", "search": "", "hash": "" }, { "input": "file:\\\\localhost//", "base": "about:blank", - "href": "file:///", + "href": "file:////", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", - "pathname": "/", + "pathname": "//", "search": "", "hash": "" }, @@ -5487,42 +5515,42 @@ { "input": "file://\\/localhost//cat", "base": "about:blank", - "href": "file:///localhost//cat", + "href": "file:////localhost//cat", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", - "pathname": "/localhost//cat", + "pathname": "//localhost//cat", "search": "", "hash": "" }, { "input": "file://localhost//a//../..//", "base": "about:blank", - "href": "file:///", + "href": "file://///", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", - "pathname": "/", + "pathname": "///", "search": "", "hash": "" }, { "input": "/////mouse", "base": "file:///elephant", - "href": "file:///mouse", + "href": "file://///mouse", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", - "pathname": "/mouse", + "pathname": "///mouse", "search": "", "hash": "" }, @@ -5543,42 +5571,42 @@ { "input": "\\/localhost//pig", "base": "file://lion/", - "href": "file:///pig", + "href": "file:////pig", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", - "pathname": "/pig", + "pathname": "//pig", "search": "", "hash": "" }, { "input": "//localhost//pig", "base": "file://lion/", - "href": "file:///pig", + "href": "file:////pig", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", - "pathname": "/pig", + "pathname": "//pig", "search": "", "hash": "" }, { "input": "/..//localhost//pig", "base": "file://lion/", - "href": "file://lion/localhost//pig", + "href": "file://lion//localhost//pig", "protocol": "file:", "username": "", "password": "", "host": "lion", "hostname": "lion", "port": "", - "pathname": "/localhost//pig", + "pathname": "//localhost//pig", "search": "", "hash": "" }, @@ -5629,12 +5657,12 @@ { "input": "C|", "base": "file://host/dir/file", - "href": "file:///C:", + "href": "file://host/C:", "protocol": "file:", "username": "", "password": "", - "host": "", - "hostname": "", + "host": "host", + "hostname": "host", "port": "", "pathname": "/C:", "search": "", @@ -5643,12 +5671,12 @@ { "input": "C|#", "base": "file://host/dir/file", - "href": "file:///C:#", + "href": "file://host/C:#", "protocol": "file:", "username": "", "password": "", - "host": "", - "hostname": "", + "host": "host", + "hostname": "host", "port": "", "pathname": "/C:", "search": "", @@ -5657,12 +5685,12 @@ { "input": "C|?", "base": "file://host/dir/file", - "href": "file:///C:?", + "href": "file://host/C:?", "protocol": "file:", "username": "", "password": "", - "host": "", - "hostname": "", + "host": "host", + "hostname": "host", "port": "", "pathname": "/C:", "search": "", @@ -5671,12 +5699,12 @@ { "input": "C|/", "base": "file://host/dir/file", - "href": "file:///C:/", + "href": "file://host/C:/", "protocol": "file:", "username": "", "password": "", - "host": "", - "hostname": "", + "host": "host", + "hostname": "host", "port": "", "pathname": "/C:/", "search": "", @@ -5685,12 +5713,12 @@ { "input": "C|\n/", "base": "file://host/dir/file", - "href": "file:///C:/", + "href": "file://host/C:/", "protocol": "file:", "username": "", "password": "", - "host": "", - "hostname": "", + "host": "host", + "hostname": "host", "port": "", "pathname": "/C:/", "search": "", @@ -5699,12 +5727,12 @@ { "input": "C|\\", "base": "file://host/dir/file", - "href": "file:///C:/", + "href": "file://host/C:/", "protocol": "file:", "username": "", "password": "", - "host": "", - "hostname": "", + "host": "host", + "hostname": "host", "port": "", "pathname": "/C:/", "search": "", @@ -5784,27 +5812,27 @@ { "input": "/c:/foo/bar", "base": "file://host/path", - "href": "file:///c:/foo/bar", + "href": "file://host/c:/foo/bar", "protocol": "file:", "username": "", "password": "", - "host": "", - "hostname": "", + "host": "host", + "hostname": "host", "port": "", "pathname": "/c:/foo/bar", "search": "", "hash": "" }, - "# Windows drive letter quirk with not empty host", + "# Do not drop the host in the presence of a drive letter", { "input": "file://example.net/C:/", "base": "about:blank", - "href": "file:///C:/", + "href": "file://example.net/C:/", "protocol": "file:", "username": "", "password": "", - "host": "", - "hostname": "", + "host": "example.net", + "hostname": "example.net", "port": "", "pathname": "/C:/", "search": "", @@ -5813,12 +5841,12 @@ { "input": "file://1.2.3.4/C:/", "base": "about:blank", - "href": "file:///C:/", + "href": "file://1.2.3.4/C:/", "protocol": "file:", "username": "", "password": "", - "host": "", - "hostname": "", + "host": "1.2.3.4", + "hostname": "1.2.3.4", "port": "", "pathname": "/C:/", "search": "", @@ -5827,12 +5855,12 @@ { "input": "file://[1::8]/C:/", "base": "about:blank", - "href": "file:///C:/", + "href": "file://[1::8]/C:/", "protocol": "file:", "username": "", "password": "", - "host": "", - "hostname": "", + "host": "[1::8]", + "hostname": "[1::8]", "port": "", "pathname": "/C:/", "search": "", @@ -6034,6 +6062,133 @@ "base": "about:blank", "failure": true }, + "# Additional file URL tetsts for (https://github.com/whatwg/url/issues/405)", + { + "input": "file://localhost//a//../..//foo", + "base": "about:blank", + "href": "file://///foo", + "protocol": "file:", + "username": "", + "password": "", + "host": "", + "hostname": "", + "port": "", + "pathname": "///foo", + "search": "", + "hash": "" + }, + { + "input": "file://localhost////foo", + "base": "about:blank", + "href": "file://////foo", + "protocol": "file:", + "username": "", + "password": "", + "host": "", + "hostname": "", + "port": "", + "pathname": "////foo", + "search": "", + "hash": "" + }, + { + "input": "file:////foo", + "base": "about:blank", + "href": "file:////foo", + "protocol": "file:", + "username": "", + "password": "", + "host": "", + "hostname": "", + "port": "", + "pathname": "//foo", + "search": "", + "hash": "" + }, + { + "input": "file:///one/two", + "base": "file:///", + "href": "file:///one/two", + "protocol": "file:", + "username": "", + "password": "", + "host": "", + "hostname": "", + "port": "", + "pathname": "/one/two", + "search": "", + "hash": "" + }, + { + "input": "file:////one/two", + "base": "file:///", + "href": "file:////one/two", + "protocol": "file:", + "username": "", + "password": "", + "host": "", + "hostname": "", + "port": "", + "pathname": "//one/two", + "search": "", + "hash": "" + }, + { + "input": "//one/two", + "base": "file:///", + "href": "file://one/two", + "protocol": "file:", + "username": "", + "password": "", + "host": "one", + "hostname": "one", + "port": "", + "pathname": "/two", + "search": "", + "hash": "" + }, + { + "input": "///one/two", + "base": "file:///", + "href": "file:///one/two", + "protocol": "file:", + "username": "", + "password": "", + "host": "", + "hostname": "", + "port": "", + "pathname": "/one/two", + "search": "", + "hash": "" + }, + { + "input": "////one/two", + "base": "file:///", + "href": "file:////one/two", + "protocol": "file:", + "username": "", + "password": "", + "host": "", + "hostname": "", + "port": "", + "pathname": "//one/two", + "search": "", + "hash": "" + }, + { + "input": "file:///.//", + "base": "file:////", + "href": "file:////", + "protocol": "file:", + "username": "", + "password": "", + "host": "", + "hostname": "", + "port": "", + "pathname": "//", + "search": "", + "hash": "" + }, "# IPv6 tests", { "input": "http://[1:0::]", @@ -7217,4 +7372,4 @@ "search": "", "username": "user" } -] \ No newline at end of file +] diff --git a/LayoutTests/imported/w3c/web-platform-tests/url/url-constructor-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/url/url-constructor-expected.txt index 86bf240e20982..ce1051af8356c 100644 --- a/LayoutTests/imported/w3c/web-platform-tests/url/url-constructor-expected.txt +++ b/LayoutTests/imported/w3c/web-platform-tests/url/url-constructor-expected.txt @@ -420,6 +420,8 @@ PASS Parsing: against against PASS Parsing: <..> against PASS Parsing: against +PASS Parsing: against +PASS Parsing: against PASS Parsing: against PASS Parsing: against PASS Parsing: <..> against @@ -430,24 +432,24 @@ PASS Parsing: against PASS Parsing: against PASS Parsing: <#x> against PASS Parsing: against -FAIL Parsing: against assert_equals: href expected "file:///" but got "file:////" -FAIL Parsing: against assert_equals: href expected "file:///" but got "file:////" -FAIL Parsing: against assert_equals: href expected "file:///?fox" but got "file:////?fox" -FAIL Parsing: against assert_equals: href expected "file:///#guppy" but got "file:////#guppy" -FAIL Parsing: against assert_equals: href expected "file://spider/" but got "file://spider///" -FAIL Parsing: against assert_equals: href expected "file:///" but got "file:////" +PASS Parsing: against +PASS Parsing: against +PASS Parsing: against +PASS Parsing: against +PASS Parsing: against +PASS Parsing: against PASS Parsing: against -FAIL Parsing: against assert_equals: href expected "file:///localhost//cat" but got "file:////localhost//cat" -FAIL Parsing: against assert_equals: href expected "file:///" but got "file://///" -FAIL Parsing: against assert_equals: href expected "file:///mouse" but got "file://///mouse" +PASS Parsing: against +PASS Parsing: against +PASS Parsing: against PASS Parsing: <\//pig> against -FAIL Parsing: <\/localhost//pig> against assert_equals: href expected "file:///pig" but got "file:////pig" -FAIL Parsing: against assert_equals: href expected "file:///pig" but got "file:////pig" -FAIL Parsing: against assert_equals: href expected "file://lion/localhost//pig" but got "file:////localhost//pig" +PASS Parsing: <\/localhost//pig> against +PASS Parsing: against +PASS Parsing: against PASS Parsing: against -FAIL Parsing: against assert_equals: href expected "file://tea/rooibos" but got "file:///rooibos" -FAIL Parsing: against assert_equals: href expected "file://tea/?chai" but got "file:///?chai" -FAIL Parsing: against assert_equals: href expected "file:///C:" but got "file://host/dir/C|" +PASS Parsing: against +PASS Parsing: against +FAIL Parsing: against assert_equals: href expected "file://host/C:" but got "file://host/dir/C|" PASS Parsing: against PASS Parsing: against PASS Parsing: against @@ -460,9 +462,9 @@ PASS Parsing: against PASS Parsing: against PASS Parsing: against PASS Parsing: against -FAIL Parsing: against assert_equals: href expected "file:///C:/" but got "file://example.net/C:/" -FAIL Parsing: against assert_equals: href expected "file:///C:/" but got "file://1.2.3.4/C:/" -FAIL Parsing: against assert_equals: href expected "file:///C:/" but got "file://[1::8]/C:/" +PASS Parsing: against +PASS Parsing: against +PASS Parsing: against PASS Parsing: against PASS Parsing: against PASS Parsing: against @@ -478,6 +480,15 @@ PASS Parsing: against PASS Parsing: against PASS Parsing: against PASS Parsing: <\\\.\y:> against +PASS Parsing: against +PASS Parsing: against +PASS Parsing: against +PASS Parsing: against +PASS Parsing: against +PASS Parsing: against +PASS Parsing: against +PASS Parsing: against +PASS Parsing: against PASS Parsing: against PASS Parsing: against PASS Parsing: against diff --git a/Source/WTF/ChangeLog b/Source/WTF/ChangeLog index 60140330d5496..b7706f3dbb942 100644 --- a/Source/WTF/ChangeLog +++ b/Source/WTF/ChangeLog @@ -1,3 +1,27 @@ +2020-10-02 Alex Christensen + + Copy host from base file URL + https://bugs.webkit.org/show_bug.cgi?id=217170 + + Reviewed by Brady Eidson. + + This matches Chrome and the URL specification. + Covered by newly passing web platform tests. + + I also updated the web platform tests from https://github.com/web-platform-tests/wpt/pull/25716 + which aligns with Safari in cases except copying of the host from base file URLs. + + The implementation pushes copying from the base URL downstream in the parsing process to where it is in the URL specification + so that we can properly decide how much of the base URL to copy and so we can copy it into the right place in the result URL. + + I also updated an assertion that makes sure that we re-use the input String if possible because there are cases where we copy + part of the parent URL, which is a "syntax violation" (meaning we copy the string parts and assemble a new one), then re-assemble + a new String that is equal to the input string. This is not a problem, it just needed to be reflected in the assertion. + + * wtf/URLParser.cpp: + (WTF::URLParser::URLParser): + (WTF::URLParser::parse): + 2020-10-02 Youenn Fablet Add AVAssetWriter SPI header diff --git a/Source/WTF/wtf/URLParser.cpp b/Source/WTF/wtf/URLParser.cpp index 6003fe2c00438..52ee6e55a637d 100644 --- a/Source/WTF/wtf/URLParser.cpp +++ b/Source/WTF/wtf/URLParser.cpp @@ -1074,8 +1074,8 @@ URLParser::URLParser(const String& input, const URL& base, const URLTextEncoding ASSERT(!m_url.m_isValid || m_didSeeSyntaxViolation == (m_url.string() != input) - || (input.isAllSpecialCharacters() - && m_url.m_string == base.m_string.left(base.m_queryEnd))); + || (input.isAllSpecialCharacters() && m_url.m_string == base.m_string.left(base.m_queryEnd)) + || (base.isValid() && base.protocolIs("file"))); ASSERT(internalValuesConsistent(m_url)); #if ASSERT_ENABLED if (!m_didSeeSyntaxViolation) { @@ -1265,8 +1265,6 @@ void URLParser::parse(const CharacterType* input, const unsigned length, const U state = State::Relative; break; } - copyURLPartsUntil(base, URLPart::SchemeEnd, c, nonUTF8QueryEncoding); - appendToASCIIBuffer(':'); state = State::File; break; case State::SpecialRelativeOrAuthority: @@ -1529,13 +1527,26 @@ void URLParser::parse(const CharacterType* input, const unsigned length, const U if (base.isValid() && base.protocolIs("file") && shouldCopyFileURL(c)) copyURLPartsUntil(base, URLPart::PathAfterLastSlash, c, nonUTF8QueryEncoding); else { - appendToASCIIBuffer("///", 3); - m_url.m_userStart = currentPosition(c) - 1; - 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_portLength = 0; - m_url.m_pathAfterLastSlash = m_url.m_userStart + 1; + bool copiedHost = false; + if (base.isValid() && base.protocolIs("file")) { + if (base.host().isEmpty()) { + copyURLPartsUntil(base, URLPart::SchemeEnd, c, nonUTF8QueryEncoding); + appendToASCIIBuffer(":///", 4); + } else { + copyURLPartsUntil(base, URLPart::PortEnd, c, nonUTF8QueryEncoding); + appendToASCIIBuffer('/'); + copiedHost = true; + } + } else + appendToASCIIBuffer("///", 3); + if (!copiedHost) { + m_url.m_userStart = currentPosition(c) - 1; + 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_portLength = 0; + } + m_url.m_pathAfterLastSlash = m_url.m_hostEnd + 1; if (isWindowsDriveLetter(c)) appendWindowsDriveLetter(c); } @@ -1548,6 +1559,10 @@ void URLParser::parse(const CharacterType* input, const unsigned length, const U if (LIKELY(*c == '/' || *c == '\\')) { if (UNLIKELY(*c == '\\')) syntaxViolation(c); + if (base.isValid() && base.protocolIs("file")) { + copyURLPartsUntil(base, URLPart::SchemeEnd, c, nonUTF8QueryEncoding); + appendToASCIIBuffer(":/", 2); + } appendToASCIIBuffer('/'); advance(c); m_url.m_userStart = currentPosition(c); @@ -1559,21 +1574,37 @@ void URLParser::parse(const CharacterType* input, const unsigned length, const U state = State::FileHost; break; } - syntaxViolation(c); - appendToASCIIBuffer("//", 2); - m_url.m_userStart = currentPosition(c) - 1; - 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_portLength = 0; + { + bool copiedHost = false; + if (base.isValid() && base.protocolIs("file")) { + if (base.host().isEmpty()) { + copyURLPartsUntil(base, URLPart::SchemeEnd, c, nonUTF8QueryEncoding); + appendToASCIIBuffer(":///", 4); + } else { + copyURLPartsUntil(base, URLPart::PortEnd, c, nonUTF8QueryEncoding); + appendToASCIIBuffer('/'); + copiedHost = true; + } + } else { + syntaxViolation(c); + appendToASCIIBuffer("//", 2); + } + if (!copiedHost) { + m_url.m_userStart = currentPosition(c) - 1; + 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_portLength = 0; + } + } if (isWindowsDriveLetter(c)) { appendWindowsDriveLetter(c); - m_url.m_pathAfterLastSlash = m_url.m_userStart + 1; + m_url.m_pathAfterLastSlash = m_url.m_hostEnd + 1; } else if (copyBaseWindowsDriveLetter(base)) { appendToASCIIBuffer('/'); - m_url.m_pathAfterLastSlash = m_url.m_userStart + 4; + m_url.m_pathAfterLastSlash = m_url.m_hostEnd + 4; } else - m_url.m_pathAfterLastSlash = m_url.m_userStart + 1; + m_url.m_pathAfterLastSlash = m_url.m_hostEnd + 1; state = State::Path; break; case State::FileHost: @@ -1864,17 +1895,32 @@ void URLParser::parse(const CharacterType* input, const unsigned length, const U case State::FileSlash: LOG_FINAL_STATE("FileSlash"); syntaxViolation(c); - m_url.m_userStart = currentPosition(c) + 1; - appendToASCIIBuffer("//", 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_portLength = 0; + { + bool copiedHost = false; + if (base.isValid() && base.protocolIs("file")) { + if (base.host().isEmpty()) { + copyURLPartsUntil(base, URLPart::SchemeEnd, c, nonUTF8QueryEncoding); + appendToASCIIBuffer(":/", 2); + } else { + copyURLPartsUntil(base, URLPart::PortEnd, c, nonUTF8QueryEncoding); + appendToASCIIBuffer('/'); + copiedHost = true; + } + } + if (!copiedHost) { + m_url.m_userStart = currentPosition(c) + 1; + appendToASCIIBuffer("//", 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_portLength = 0; + } + } if (copyBaseWindowsDriveLetter(base)) { appendToASCIIBuffer('/'); - m_url.m_pathAfterLastSlash = m_url.m_userStart + 4; + m_url.m_pathAfterLastSlash = m_url.m_hostEnd + 4; } else - m_url.m_pathAfterLastSlash = m_url.m_userStart + 1; + m_url.m_pathAfterLastSlash = m_url.m_hostEnd + 1; m_url.m_pathEnd = m_url.m_pathAfterLastSlash; m_url.m_queryEnd = m_url.m_pathAfterLastSlash; break; @@ -1956,7 +2002,7 @@ void URLParser::parse(const CharacterType* input, const unsigned length, const U } else m_url.m_string = String::adopt(WTFMove(m_asciiBuffer)); m_url.m_isValid = true; - URL_PARSER_LOG("Parsed URL <%s>", m_url.m_string.utf8().data()); + URL_PARSER_LOG("Parsed URL <%s>\n\n", m_url.m_string.utf8().data()); } template