From c822b85b5de353175f66f17c6b18a2b9dd1dfba4 Mon Sep 17 00:00:00 2001 From: = Date: Fri, 3 Jul 2020 17:02:57 +0200 Subject: [PATCH] fixup --- lib/internal/per_context/domexception.js | 23 +- test/common/wpt.js | 5 +- test/fixtures/wpt/README.md | 2 +- .../wpt/url/resources/setters_tests.json | 24 +- test/fixtures/wpt/url/resources/toascii.json | 22 ++ .../wpt/url/resources/urltestdata.json | 338 +++++++++++++++++- .../wpt/url/url-setters-stripping.any.js | 125 +++++++ .../fixtures/wpt/url/urlencoded-parser.any.js | 6 +- .../url/urlsearchparams-constructor.any.js | 39 ++ .../url/urlsearchparams-stringifier.any.js | 12 + test/fixtures/wpt/versions.json | 2 +- test/wpt/status/url.json | 12 + 12 files changed, 580 insertions(+), 30 deletions(-) create mode 100644 test/fixtures/wpt/url/url-setters-stripping.any.js diff --git a/lib/internal/per_context/domexception.js b/lib/internal/per_context/domexception.js index c6d6370c5547cd..de2cb762a9b30e 100644 --- a/lib/internal/per_context/domexception.js +++ b/lib/internal/per_context/domexception.js @@ -7,14 +7,25 @@ const { SafeWeakMap, SafeMap, SymbolToStringTag, + TypeError, } = primordials; -class ERR_INVALID_THIS extends TypeError { - constructor(type) { - super('Value of "this" must be of ' + type); - } - - get code() { return 'ERR_INVALID_THIS'; } +function ERR_INVALID_THIS(type) { + // eslint-disable-next-line no-restricted-syntax + const error = new TypeError(`Value of "this" must be of type ${type}`); + ObjectDefineProperty(error, 'toString', { + value() { + return `${this.name} [ERR_INVALID_THIS]: ${this.message}`; + }, + enumerable: false, + writable: true, + configurable: true, + }); + error.name = 'TypeError [ERR_INVALID_THIS]'; + error.stack; + delete error.name; + error.code = 'ERR_INVALID_THIS'; + return error; } let internalsMap; diff --git a/test/common/wpt.js b/test/common/wpt.js index e79bd66b370735..8b63e8eb0a1f34 100644 --- a/test/common/wpt.js +++ b/test/common/wpt.js @@ -442,7 +442,10 @@ class WPTRunner { GLOBAL: { isWindow() { return false; } }, - Object + Object, + Error, + RangeError, + TypeError, }; return result; diff --git a/test/fixtures/wpt/README.md b/test/fixtures/wpt/README.md index b915b53099e076..6e4e14f0ca6b1b 100644 --- a/test/fixtures/wpt/README.md +++ b/test/fixtures/wpt/README.md @@ -12,7 +12,7 @@ Last update: - console: https://github.com/web-platform-tests/wpt/tree/b0daaa6b86/console - encoding: https://github.com/web-platform-tests/wpt/tree/ab733fd9f5/encoding -- url: https://github.com/web-platform-tests/wpt/tree/3696f2233a/url +- url: https://github.com/web-platform-tests/wpt/tree/c8cd629083/url - resources: https://github.com/web-platform-tests/wpt/tree/abfd8c9729/resources - interfaces: https://github.com/web-platform-tests/wpt/tree/3cbf8e150b/interfaces - html/webappapis/microtask-queuing: https://github.com/web-platform-tests/wpt/tree/2c5c3c4c27/html/webappapis/microtask-queuing diff --git a/test/fixtures/wpt/url/resources/setters_tests.json b/test/fixtures/wpt/url/resources/setters_tests.json index d54335f1badeca..6c011e2f9acae4 100644 --- a/test/fixtures/wpt/url/resources/setters_tests.json +++ b/test/fixtures/wpt/url/resources/setters_tests.json @@ -1848,12 +1848,30 @@ } }, { - "comment": "Simple percent-encoding; nuls, tabs, and newlines are removed", + "comment": "Simple percent-encoding; tabs and newlines are removed", "href": "a:/", "new_value": "\u0000\u0001\t\n\r\u001f !\"#$%&'()*+,-./09:;<=>?@AZ[\\]^_`az{|}~\u007f\u0080\u0081Éé", "expected": { - "href": "a:/#%01%1F%20!%22#$%&'()*+,-./09:;%3C=%3E?@AZ[\\]^_%60az{|}~%7F%C2%80%C2%81%C3%89%C3%A9", - "hash": "#%01%1F%20!%22#$%&'()*+,-./09:;%3C=%3E?@AZ[\\]^_%60az{|}~%7F%C2%80%C2%81%C3%89%C3%A9" + "href": "a:/#%00%01%1F%20!%22#$%&'()*+,-./09:;%3C=%3E?@AZ[\\]^_%60az{|}~%7F%C2%80%C2%81%C3%89%C3%A9", + "hash": "#%00%01%1F%20!%22#$%&'()*+,-./09:;%3C=%3E?@AZ[\\]^_%60az{|}~%7F%C2%80%C2%81%C3%89%C3%A9" + } + }, + { + "comment": "Percent-encode NULLs in fragment", + "href": "http://example.net", + "new_value": "a\u0000b", + "expected": { + "href": "http://example.net/#a%00b", + "hash": "#a%00b" + } + }, + { + "comment": "Percent-encode NULLs in fragment", + "href": "non-spec:/", + "new_value": "a\u0000b", + "expected": { + "href": "non-spec:/#a%00b", + "hash": "#a%00b" } }, { diff --git a/test/fixtures/wpt/url/resources/toascii.json b/test/fixtures/wpt/url/resources/toascii.json index 814f06e794866d..1fb57673816e43 100644 --- a/test/fixtures/wpt/url/resources/toascii.json +++ b/test/fixtures/wpt/url/resources/toascii.json @@ -145,5 +145,27 @@ { "input": "01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.0123456789012345678901234567890123456789012345678.β", "output": "01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.0123456789012345678901234567890123456789012345678.xn--nxa" + }, + { + "comment": "IDNA ignored code points", + "input": "a\u00ADb", + "output": "ab" + }, + { + "input": "a%C2%ADb", + "output": "ab" + }, + { + "comment": "Empty host after domain to ASCII", + "input": "\u00AD", + "output": null + }, + { + "input": "%C2%AD", + "output": null + }, + { + "input": "xn--", + "output": null } ] diff --git a/test/fixtures/wpt/url/resources/urltestdata.json b/test/fixtures/wpt/url/resources/urltestdata.json index 32ed1959430c13..ded7107ff757d2 100644 --- a/test/fixtures/wpt/url/resources/urltestdata.json +++ b/test/fixtures/wpt/url/resources/urltestdata.json @@ -4481,21 +4481,6 @@ "search": "", "hash": "" }, - { - "input": "sc://\u001F!\"$&'()*+,-.;<=>^_`{|}~/", - "base": "about:blank", - "href": "sc://%1F!\"$&'()*+,-.;<=>^_`{|}~/", - "origin": "null", - "protocol": "sc:", - "username": "", - "password": "", - "host": "%1F!\"$&'()*+,-.;<=>^_`{|}~", - "hostname": "%1F!\"$&'()*+,-.;<=>^_`{|}~", - "port": "", - "pathname": "/", - "search": "", - "hash": "" - }, { "input": "sc://\u0000/", "base": "about:blank", @@ -4649,6 +4634,68 @@ "search": "", "hash": "" }, + "Forbidden host code points", + { + "input": "http://ab", + "base": "about:blank", + "failure": true + }, + { + "input": "http://a^b", + "base": "about:blank", + "failure": true + }, + { + "input": "non-special://ab", + "base": "about:blank", + "failure": true + }, + { + "input": "non-special://a^b", + "base": "about:blank", + "failure": true + }, + "Allowed host code points", + { + "input": "http://\u001F!\"$&'()*+,-.;=_`{|}~/", + "base": "about:blank", + "href": "http://\u001F!\"$&'()*+,-.;=_`{|}~/", + "origin": "http://\u001F!\"$&'()*+,-.;=_`{|}~", + "protocol": "http:", + "username": "", + "password": "", + "host": "\u001F!\"$&'()*+,-.;=_`{|}~", + "hostname": "\u001F!\"$&'()*+,-.;=_`{|}~", + "port": "", + "pathname": "/", + "search": "", + "hash": "" + }, + { + "input": "sc://\u001F!\"$&'()*+,-.;=_`{|}~/", + "base": "about:blank", + "href": "sc://%1F!\"$&'()*+,-.;=_`{|}~/", + "origin": "null", + "protocol": "sc:", + "username": "", + "password": "", + "host": "%1F!\"$&'()*+,-.;=_`{|}~", + "hostname": "%1F!\"$&'()*+,-.;=_`{|}~", + "port": "", + "pathname": "/", + "search": "", + "hash": "" + }, "# Hosts and percent-encoding", { "input": "ftp://example.com%80/", @@ -5863,6 +5910,130 @@ "search": "", "hash": "#frag" }, + "# file: drive letter cases from https://crbug.com/1078698", + { + "input": "file:///Y:", + "base": "about:blank", + "href": "file:///Y:", + "protocol": "file:", + "username": "", + "password": "", + "host": "", + "hostname": "", + "port": "", + "pathname": "/Y:", + "search": "", + "hash": "" + }, + { + "input": "file:///Y:/", + "base": "about:blank", + "href": "file:///Y:/", + "protocol": "file:", + "username": "", + "password": "", + "host": "", + "hostname": "", + "port": "", + "pathname": "/Y:/", + "search": "", + "hash": "" + }, + { + "input": "file:///./Y", + "base": "about:blank", + "href": "file:///Y", + "protocol": "file:", + "username": "", + "password": "", + "host": "", + "hostname": "", + "port": "", + "pathname": "/Y", + "search": "", + "hash": "" + }, + { + "input": "file:///./Y:", + "base": "about:blank", + "href": "file:///Y:", + "protocol": "file:", + "username": "", + "password": "", + "host": "", + "hostname": "", + "port": "", + "pathname": "/Y:", + "search": "", + "hash": "" + }, + { + "input": "\\\\\\.\\Y:", + "base": "about:blank", + "failure": true + }, + "# file: drive letter cases from https://crbug.com/1078698 but lowercased", + { + "input": "file:///y:", + "base": "about:blank", + "href": "file:///y:", + "protocol": "file:", + "username": "", + "password": "", + "host": "", + "hostname": "", + "port": "", + "pathname": "/y:", + "search": "", + "hash": "" + }, + { + "input": "file:///y:/", + "base": "about:blank", + "href": "file:///y:/", + "protocol": "file:", + "username": "", + "password": "", + "host": "", + "hostname": "", + "port": "", + "pathname": "/y:/", + "search": "", + "hash": "" + }, + { + "input": "file:///./y", + "base": "about:blank", + "href": "file:///y", + "protocol": "file:", + "username": "", + "password": "", + "host": "", + "hostname": "", + "port": "", + "pathname": "/y", + "search": "", + "hash": "" + }, + { + "input": "file:///./y:", + "base": "about:blank", + "href": "file:///y:", + "protocol": "file:", + "username": "", + "password": "", + "host": "", + "hostname": "", + "port": "", + "pathname": "/y:", + "search": "", + "hash": "" + }, + { + "input": "\\\\\\.\\y:", + "base": "about:blank", + "failure": true + }, "# IPv6 tests", { "input": "http://[1:0::]", @@ -6672,7 +6843,7 @@ { "input": "http://example.org/test?a#b\u0000c", "base": "about:blank", - "href": "http://example.org/test?a#bc", + "href": "http://example.org/test?a#b%00c", "protocol": "http:", "username": "", "password": "", @@ -6681,6 +6852,139 @@ "port": "", "pathname": "/test", "search": "?a", - "hash": "#bc" + "hash": "#b%00c" + }, + { + "input": "non-spec://example.org/test?a#b\u0000c", + "base": "about:blank", + "href": "non-spec://example.org/test?a#b%00c", + "protocol": "non-spec:", + "username": "", + "password": "", + "host": "example.org", + "hostname": "example.org", + "port": "", + "pathname": "/test", + "search": "?a", + "hash": "#b%00c" + }, + { + "input": "non-spec:/test?a#b\u0000c", + "base": "about:blank", + "href": "non-spec:/test?a#b%00c", + "protocol": "non-spec:", + "username": "", + "password": "", + "host": "", + "hostname": "", + "port": "", + "pathname": "/test", + "search": "?a", + "hash": "#b%00c" + }, + "First scheme char - not allowed: https://github.com/whatwg/url/issues/464", + { + "input": "10.0.0.7:8080/foo.html", + "base": "file:///some/dir/bar.html", + "href": "file:///some/dir/10.0.0.7:8080/foo.html", + "protocol": "file:", + "username": "", + "password": "", + "host": "", + "hostname": "", + "port": "", + "pathname": "/some/dir/10.0.0.7:8080/foo.html", + "search": "", + "hash": "" + }, + "Subsequent scheme chars - not allowed", + { + "input": "a!@$*=/foo.html", + "base": "file:///some/dir/bar.html", + "href": "file:///some/dir/a!@$*=/foo.html", + "protocol": "file:", + "username": "", + "password": "", + "host": "", + "hostname": "", + "port": "", + "pathname": "/some/dir/a!@$*=/foo.html", + "search": "", + "hash": "" + }, + "First and subsequent scheme chars - allowed", + { + "input": "a1234567890-+.:foo/bar", + "base": "http://example.com/dir/file", + "href": "a1234567890-+.:foo/bar", + "protocol": "a1234567890-+.:", + "username": "", + "password": "", + "host": "", + "hostname": "", + "port": "", + "pathname": "foo/bar", + "search": "", + "hash": "" + }, + "IDNA ignored code points in file URLs hosts", + { + "input": "file://a\u00ADb/p", + "base": "about:blank", + "href": "file://ab/p", + "protocol": "file:", + "username": "", + "password": "", + "host": "ab", + "hostname": "ab", + "port": "", + "pathname": "/p", + "search": "", + "hash": "" + }, + { + "input": "file://a%C2%ADb/p", + "base": "about:blank", + "href": "file://ab/p", + "protocol": "file:", + "username": "", + "password": "", + "host": "ab", + "hostname": "ab", + "port": "", + "pathname": "/p", + "search": "", + "hash": "" + }, + "Empty host after the domain to ASCII", + { + "input": "file://\u00ad/p", + "base": "about:blank", + "failure": true + }, + { + "input": "file://%C2%AD/p", + "base": "about:blank", + "failure": true + }, + { + "input": "file://xn--/p", + "base": "about:blank", + "failure": true + }, + "https://bugzilla.mozilla.org/show_bug.cgi?id=1647058", + { + "input": "#link", + "base": "https://example.org/##link", + "href": "https://example.org/#link", + "protocol": "https:", + "username": "", + "password": "", + "host": "example.org", + "hostname": "example.org", + "port": "", + "pathname": "/", + "search": "", + "hash": "#link" } ] diff --git a/test/fixtures/wpt/url/url-setters-stripping.any.js b/test/fixtures/wpt/url/url-setters-stripping.any.js new file mode 100644 index 00000000000000..3413c6cd5ad21d --- /dev/null +++ b/test/fixtures/wpt/url/url-setters-stripping.any.js @@ -0,0 +1,125 @@ +function urlString({ scheme = "https", + username = "username", + password = "password", + host = "host", + port = "8000", + pathname = "path", + search = "query", + hash = "fragment" }) { + return `${scheme}://${username}:${password}@${host}:${port}/${pathname}?${search}#${hash}`; +} + +function urlRecord(scheme) { + return new URL(urlString({ scheme })); +} + +for(const scheme of ["https", "wpt++"]) { + for(let i = 0; i < 0x20; i++) { + const stripped = i === 0x09 || i === 0x0A || i === 0x0D; + + // It turns out that user agents are surprisingly similar for these ranges so generate fewer + // tests. If this is changed also change the logic for host below. + if (i !== 0 && i !== 0x1F && !stripped) { + continue; + } + + const cpString = String.fromCodePoint(i); + const cpReference = "U+" + i.toString(16).toUpperCase().padStart(4, "0"); + + test(() => { + const expected = scheme === "https" ? (stripped ? "http" : "https") : (stripped ? "wpt--" : "wpt++"); + const url = urlRecord(scheme); + url.protocol = String.fromCodePoint(i) + (scheme === "https" ? "http" : "wpt--"); + assert_equals(url.protocol, expected + ":", "property"); + assert_equals(url.href, urlString({ scheme: expected }), "href"); + }, `Setting protocol with leading ${cpReference} (${scheme}:)`); + + test(() => { + const expected = scheme === "https" ? (stripped ? "http" : "https") : (stripped ? "wpt--" : "wpt++"); + const url = urlRecord(scheme); + url.protocol = (scheme === "https" ? "http" : "wpt--") + String.fromCodePoint(i); + assert_equals(url.protocol, expected + ":", "property"); + assert_equals(url.href, urlString({ scheme: expected }), "href"); + }, `Setting protocol with ${cpReference} before inserted colon (${scheme}:)`); + + // Cannot test protocol with trailing as the algorithm inserts a colon before proceeding + + // These do no stripping + for (const property of ["username", "password"]) { + for (const [type, expected, input] of [ + ["leading", encodeURIComponent(cpString) + "test", String.fromCodePoint(i) + "test"], + ["middle", "te" + encodeURIComponent(cpString) + "st", "te" + String.fromCodePoint(i) + "st"], + ["trailing", "test" + encodeURIComponent(cpString), "test" + String.fromCodePoint(i)] + ]) { + test(() => { + const url = urlRecord(scheme); + url[property] = input; + assert_equals(url[property], expected, "property"); + assert_equals(url.href, urlString({ scheme, [property]: expected }), "href"); + }, `Setting ${property} with ${type} ${cpReference} (${scheme}:)`); + } + } + + for (const [type, expectedPart, input] of [ + ["leading", (scheme === "https" ? cpString : encodeURIComponent(cpString)) + "test", String.fromCodePoint(i) + "test"], + ["middle", "te" + (scheme === "https" ? cpString : encodeURIComponent(cpString)) + "st", "te" + String.fromCodePoint(i) + "st"], + ["trailing", "test" + (scheme === "https" ? cpString : encodeURIComponent(cpString)), "test" + String.fromCodePoint(i)] + ]) { + test(() => { + const expected = i === 0x00 ? "host" : stripped ? "test" : expectedPart; + const url = urlRecord(scheme); + url.host = input; + assert_equals(url.host, expected + ":8000", "property"); + assert_equals(url.href, urlString({ scheme, host: expected }), "href"); + }, `Setting host with ${type} ${cpReference} (${scheme}:)`); + + test(() => { + const expected = i === 0x00 ? "host" : stripped ? "test" : expectedPart; + const url = urlRecord(scheme); + url.hostname = input; + assert_equals(url.hostname, expected, "property"); + assert_equals(url.href, urlString({ scheme, host: expected }), "href"); + }, `Setting hostname with ${type} ${cpReference} (${scheme}:)`); + } + + test(() => { + const expected = stripped ? "9000" : "8000"; + const url = urlRecord(scheme); + url.port = String.fromCodePoint(i) + "9000"; + assert_equals(url.port, expected, "property"); + assert_equals(url.href, urlString({ scheme, port: expected }), "href"); + }, `Setting port with leading ${cpReference} (${scheme}:)`); + + test(() => { + const expected = stripped ? "9000" : "90"; + const url = urlRecord(scheme); + url.port = "90" + String.fromCodePoint(i) + "00"; + assert_equals(url.port, expected, "property"); + assert_equals(url.href, urlString({ scheme, port: expected }), "href"); + }, `Setting port with middle ${cpReference} (${scheme}:)`); + + test(() => { + const expected = "9000"; + const url = urlRecord(scheme); + url.port = "9000" + String.fromCodePoint(i); + assert_equals(url.port, expected, "property"); + assert_equals(url.href, urlString({ scheme, port: expected }), "href"); + }, `Setting port with trailing ${cpReference} (${scheme}:)`); + + for (const [property, separator] of [["pathname", "/"], ["search", "?"], ["hash", "#"]]) { + for (const [type, expectedPart, input] of [ + ["leading", encodeURIComponent(cpString) + "test", String.fromCodePoint(i) + "test"], + ["middle", "te" + encodeURIComponent(cpString) + "st", "te" + String.fromCodePoint(i) + "st"], + ["trailing", "test" + encodeURIComponent(cpString), "test" + String.fromCodePoint(i)] + ]) { + test(() => { + const expected = stripped ? "test" : expectedPart; + const url = urlRecord(scheme); + url[property] = input; + assert_equals(url[property], separator + expected, "property"); + assert_equals(url.href, urlString({ scheme, [property]: expected }), "href"); + }, `Setting ${property} with ${type} ${cpReference} (${scheme}:)`); + } + } + } +} diff --git a/test/fixtures/wpt/url/urlencoded-parser.any.js b/test/fixtures/wpt/url/urlencoded-parser.any.js index 65e894b94c26b0..46b932bb014364 100644 --- a/test/fixtures/wpt/url/urlencoded-parser.any.js +++ b/test/fixtures/wpt/url/urlencoded-parser.any.js @@ -28,7 +28,11 @@ { "input": '%a=a', "output": [['%a', 'a']] }, { "input": '%a_=a', "output": [['%a_', 'a']] }, { "input": '%61=a', "output": [['a', 'a']] }, - { "input": '%61+%4d%4D=', "output": [['a MM', '']] } + { "input": '%61+%4d%4D=', "output": [['a MM', '']] }, + { "input": "id=0&value=%", "output": [['id', '0'], ['value', '%']] }, + { "input": "b=%2sf%2a", "output": [['b', '%2sf*']]}, + { "input": "b=%2%2af%2a", "output": [['b', '%2*f*']]}, + { "input": "b=%%2a", "output": [['b', '%*']]} ].forEach((val) => { test(() => { let sp = new URLSearchParams(val.input), diff --git a/test/fixtures/wpt/url/urlsearchparams-constructor.any.js b/test/fixtures/wpt/url/urlsearchparams-constructor.any.js index f7989f70ea0071..1135d5d3dbbfa3 100644 --- a/test/fixtures/wpt/url/urlsearchparams-constructor.any.js +++ b/test/fixtures/wpt/url/urlsearchparams-constructor.any.js @@ -56,6 +56,28 @@ test(function() { assert_false(params.has('c'), 'Search params object did not have the name "c"'); assert_true(params.has(' c'), 'Search params object has name " c"'); assert_true(params.has('møø'), 'Search params object has name "møø"'); + + params = new URLSearchParams('id=0&value=%'); + assert_true(params != null, 'constructor returned non-null value.'); + assert_true(params.has('id'), 'Search params object has name "id"'); + assert_true(params.has('value'), 'Search params object has name "value"'); + assert_equals(params.get('id'), '0'); + assert_equals(params.get('value'), '%'); + + params = new URLSearchParams('b=%2sf%2a'); + assert_true(params != null, 'constructor returned non-null value.'); + assert_true(params.has('b'), 'Search params object has name "b"'); + assert_equals(params.get('b'), '%2sf*'); + + params = new URLSearchParams('b=%2%2af%2a'); + assert_true(params != null, 'constructor returned non-null value.'); + assert_true(params.has('b'), 'Search params object has name "b"'); + assert_equals(params.get('b'), '%2*f*'); + + params = new URLSearchParams('b=%%2a'); + assert_true(params != null, 'constructor returned non-null value.'); + assert_true(params.has('b'), 'Search params object has name "b"'); + assert_equals(params.get('b'), '%*'); }, 'URLSearchParams constructor, string.'); test(function() { @@ -73,6 +95,23 @@ test(function() { assert_false(seed.has('g')); }, 'URLSearchParams constructor, object.'); +test(function() { + var formData = new FormData() + formData.append('a', 'b') + formData.append('c', 'd') + var params = new URLSearchParams(formData); + assert_true(params != null, 'constructor returned non-null value.'); + assert_equals(params.get('a'), 'b'); + assert_equals(params.get('c'), 'd'); + assert_false(params.has('d')); + // The name-value pairs are copied when created; later updates + // should not be observable. + formData.append('e', 'f'); + assert_false(params.has('e')); + params.append('g', 'h'); + assert_false(formData.has('g')); +}, 'URLSearchParams constructor, FormData.'); + test(function() { var params = new URLSearchParams('a=b+c'); assert_equals(params.get('a'), 'b c'); diff --git a/test/fixtures/wpt/url/urlsearchparams-stringifier.any.js b/test/fixtures/wpt/url/urlsearchparams-stringifier.any.js index ef95c1434c7964..bc7bedd533f58d 100644 --- a/test/fixtures/wpt/url/urlsearchparams-stringifier.any.js +++ b/test/fixtures/wpt/url/urlsearchparams-stringifier.any.js @@ -78,6 +78,9 @@ test(function() { params.delete('a'); params.append('a%b', 'c'); assert_equals(params + '', 'a%25b=c'); + + params = new URLSearchParams('id=0&value=%') + assert_equals(params + '', 'id=0&value=%25') }, 'Serialize %'); test(function() { @@ -107,6 +110,15 @@ test(function() { // The lone '=' _does_ survive the roundtrip. params = new URLSearchParams('a=&a=b'); assert_equals(params.toString(), 'a=&a=b'); + + params = new URLSearchParams('b=%2sf%2a'); + assert_equals(params.toString(), 'b=%252sf*'); + + params = new URLSearchParams('b=%2%2af%2a'); + assert_equals(params.toString(), 'b=%252*f*'); + + params = new URLSearchParams('b=%%2a'); + assert_equals(params.toString(), 'b=%25*'); }, 'URLSearchParams.toString'); test(() => { diff --git a/test/fixtures/wpt/versions.json b/test/fixtures/wpt/versions.json index 39c6dce26652e6..d56e283e1d263c 100644 --- a/test/fixtures/wpt/versions.json +++ b/test/fixtures/wpt/versions.json @@ -8,7 +8,7 @@ "path": "encoding" }, "url": { - "commit": "3696f2233a37437896505b7187968aa605be9255", + "commit": "c8cd629083f5c9f1d117003b0a12a370a5fdad0e", "path": "url" }, "resources": { diff --git a/test/wpt/status/url.json b/test/wpt/status/url.json index afd5acdcbfc455..d9b6fa6f16b427 100644 --- a/test/wpt/status/url.json +++ b/test/wpt/status/url.json @@ -11,5 +11,17 @@ }, "idlharness.any.js": { "fail": "getter/setter names are wrong, etc." + }, + "url-searchparams.any.js": { + "fail": "TypeError from other context" + }, + "url-setters-stripping.any.js": { + "fail": "TODO: port https://github.com/whatwg/url/pull/486" + }, + "urlsearchparams-constructor.any.js": { + "fail": "TODO: fix https://github.com/nodejs/node/issues/33892" + }, + "urlsearchparams-stringifier.any.js": { + "fail": "TODO: fix https://github.com/nodejs/node/issues/33892" } }