diff options
-rw-r--r-- | cli/tests/unit/url_search_params_test.ts | 37 | ||||
-rw-r--r-- | op_crates/web/11_url.js | 11 |
2 files changed, 43 insertions, 5 deletions
diff --git a/cli/tests/unit/url_search_params_test.ts b/cli/tests/unit/url_search_params_test.ts index 41b277129..dc0e8bd85 100644 --- a/cli/tests/unit/url_search_params_test.ts +++ b/cli/tests/unit/url_search_params_test.ts @@ -49,10 +49,39 @@ unitTest(function urlSearchParamsInitString(): void { }); unitTest(function urlSearchParamsInitStringWithPlusCharacter(): void { - const init = "q=a+b"; - const searchParams = new URLSearchParams(init); - assertEquals(searchParams.toString(), init); - assertEquals(searchParams.get("q"), "a b"); + let params = new URLSearchParams("q=a+b"); + assertEquals(params.toString(), "q=a+b"); + assertEquals(params.get("q"), "a b"); + + params = new URLSearchParams("q=a+b+c"); + assertEquals(params.toString(), "q=a+b+c"); + assertEquals(params.get("q"), "a b c"); +}); + +unitTest(function urlSearchParamsInitStringWithMalformedParams(): void { + // These test cases are copied from Web Platform Tests + // https://github.com/web-platform-tests/wpt/blob/54c6d64/url/urlsearchparams-constructor.any.js#L60-L80 + let params = new URLSearchParams("id=0&value=%"); + assert(params != null, "constructor returned non-null value."); + assert(params.has("id"), 'Search params object has name "id"'); + assert(params.has("value"), 'Search params object has name "value"'); + assertEquals(params.get("id"), "0"); + assertEquals(params.get("value"), "%"); + + params = new URLSearchParams("b=%2sf%2a"); + assert(params != null, "constructor returned non-null value."); + assert(params.has("b"), 'Search params object has name "b"'); + assertEquals(params.get("b"), "%2sf*"); + + params = new URLSearchParams("b=%2%2af%2a"); + assert(params != null, "constructor returned non-null value."); + assert(params.has("b"), 'Search params object has name "b"'); + assertEquals(params.get("b"), "%2*f*"); + + params = new URLSearchParams("b=%%2a"); + assert(params != null, "constructor returned non-null value."); + assert(params.has("b"), 'Search params object has name "b"'); + assertEquals(params.get("b"), "%*"); }); unitTest(function urlSearchParamsInitIterable(): void { diff --git a/op_crates/web/11_url.js b/op_crates/web/11_url.js index f2d12f5be..d60f9769a 100644 --- a/op_crates/web/11_url.js +++ b/op_crates/web/11_url.js @@ -37,7 +37,16 @@ } function decodeSearchParam(p) { - return decodeURIComponent(p.replace(/\+/g, " ")); + const s = p.replaceAll("+", " "); + const decoder = new TextDecoder(); + + return s.replace(/(%[0-9a-f]{2})+/gi, (matched) => { + const buf = new Uint8Array(Math.ceil(matched.length / 3)); + for (let i = 0, offset = 0; i < matched.length; i += 3, offset += 1) { + buf[offset] = parseInt(matched.slice(i + 1, i + 3), 16); + } + return decoder.decode(buf); + }); } const urls = new WeakMap(); |