url: do not use object as hashmap

Fixes cases like new URLSearchParams({ hasOwnProperty: 1 }).

PR-URL: https://github.com/nodejs/node/pull/47415
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
This commit is contained in:
Timothy Gu authored and GitHub committed 2023-04-07 03:32:26 +00:00
1 parent 7efae9341f
commit 0c769227ea
2 files changed
+15 -8

No files matched your search

+10 -8
View File
@@ -20,6 +20,7 @@ const {
ReflectGetOwnPropertyDescriptor,
ReflectOwnKeys,
RegExpPrototypeSymbolReplace,
SafeMap,
StringPrototypeCharAt,
StringPrototypeCharCodeAt,
StringPrototypeCodePointAt,
@@ -243,7 +244,7 @@ class URLSearchParams {
} else {
// Record<USVString, USVString>
// Need to use reflection APIs for full spec compliance.
const visited = {};
const visited = new SafeMap();
const keys = ReflectOwnKeys(init);
for (let i = 0; i < keys.length; i++) {
const key = keys[i];
@@ -252,14 +253,15 @@ class URLSearchParams {
const typedKey = toUSVString(key);
const typedValue = toUSVString(init[key]);
// Two different key may result same after `toUSVString()`, we only
// leave the later one. Refers to WPT.
if (visited[typedKey] !== undefined) {
this[searchParams][visited[typedKey]] = typedValue;
// Two different keys may become the same USVString after normalization.
// In that case, we retain the later one. Refer to WPT.
const keyIdx = visited.get(typedKey);
if (keyIdx !== undefined) {
this[searchParams][keyIdx] = typedValue;
} else {
visited[typedKey] = ArrayPrototypePush(this[searchParams],
typedKey,
typedValue) - 1;
visited.set(typedKey, ArrayPrototypePush(this[searchParams],
typedKey,
typedValue) - 1);
}
}
}
@@ -38,8 +38,13 @@ function makeIterableFunc(array) {
makeIterableFunc([['key', 'val'], ['key2', 'val2']].map(makeIterableFunc))
);
assert.strictEqual(params.toString(), 'key=val&key2=val2');
params = new URLSearchParams({ hasOwnProperty: 1 });
assert.strictEqual(params.get('hasOwnProperty'), '1');
assert.strictEqual(params.toString(), 'hasOwnProperty=1');
assert.throws(() => new URLSearchParams([[1]]), tupleError);
assert.throws(() => new URLSearchParams([[1, 2, 3]]), tupleError);
assert.throws(() => new URLSearchParams({ [Symbol('test')]: 42 }),
TypeError);
assert.throws(() => new URLSearchParams({ [Symbol.iterator]: 42 }),
iterableError);
assert.throws(() => new URLSearchParams([{}]), tupleError);