summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYoshiya Hinosawa <stibium121@gmail.com>2020-11-03 02:58:29 +0900
committerGitHub <noreply@github.com>2020-11-02 18:58:29 +0100
commit397fec63d1bacabd2b8e48bd30a1727003a7a72b (patch)
treec89ab8dbd5581836ce3290eb7df54cf1983198c4
parentc5611636fb03ce71f50a9bca958c79d23b55be00 (diff)
fix(op_crates/web): fix URLSearchParams, malformed url handling (#8092)
Co-authored-by: Evan <c4t@tuta.io>
-rw-r--r--cli/tests/unit/url_search_params_test.ts37
-rw-r--r--op_crates/web/11_url.js11
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();