Skip to content

Commit

Permalink
url: do not use object as hashmap
Browse files Browse the repository at this point in the history
Fixes cases like new URLSearchParams({ hasOwnProperty: 1 }).

PR-URL: #47415
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
  • Loading branch information
TimothyGu authored and MoLow committed Jul 6, 2023
1 parent 89a5d04 commit 9a2354d
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 8 deletions.
18 changes: 10 additions & 8 deletions lib/internal/url.js
Expand Up @@ -21,6 +21,7 @@ const {
ReflectGetOwnPropertyDescriptor,
ReflectOwnKeys,
RegExpPrototypeSymbolReplace,
SafeMap,
StringPrototypeCharAt,
StringPrototypeCharCodeAt,
StringPrototypeCodePointAt,
Expand Down Expand Up @@ -225,7 +226,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];
Expand All @@ -234,14 +235,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);
}
}
}
Expand Down
Expand Up @@ -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);
Expand Down

0 comments on commit 9a2354d

Please sign in to comment.