From 976e8d91b8d88025a16cdb94ca22b47d9e3d247b Mon Sep 17 00:00:00 2001 From: "achristensen@apple.com" Date: Fri, 2 Oct 2020 20:59:11 +0000 Subject: [PATCH] Copy host from base file URL https://bugs.webkit.org/show_bug.cgi?id=217170 Reviewed by Brady Eidson. LayoutTests/imported/w3c: * 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: Source/WTF: 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): git-svn-id: http://svn.webkit.org/repository/webkit/trunk@267896 268f45cc-cd09-0410-ab3c-d52691b4dbfc --- LayoutTests/imported/w3c/ChangeLog | 12 + .../url/a-element-expected.txt | 47 +-- .../url/a-element-xhtml-expected.txt | 47 +-- .../url/resources/urltestdata.json | 267 ++++++++++++++---- .../url/url-constructor-expected.txt | 47 +-- Source/WTF/ChangeLog | 24 ++ Source/WTF/wtf/URLParser.cpp | 106 +++++-- 7 files changed, 410 insertions(+), 140 deletions(-) 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