1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-12-22 15:24:46 -05:00

runtime arg check URLSearchParams (#1390)

This commit is contained in:
迷渡 2018-12-24 12:07:58 +08:00 committed by Ryan Dahl
parent 9909e8a759
commit 7d0e1050d3
3 changed files with 73 additions and 3 deletions

View file

@ -1,3 +1,5 @@
import { requiredArguments } from "./util";
// Copyright 2018 the Deno authors. All rights reserved. MIT license.
export class URLSearchParams {
private params: Array<[string, string]> = [];
@ -46,7 +48,8 @@ export class URLSearchParams {
* searchParams.append('name', 'second');
*/
append(name: string, value: string): void {
this.params.push([name, value]);
requiredArguments("URLSearchParams.append", arguments.length, 2);
this.params.push([String(name), value]);
}
/** Deletes the given search parameter and its associated value,
@ -55,6 +58,8 @@ export class URLSearchParams {
* searchParams.delete('name');
*/
delete(name: string): void {
requiredArguments("URLSearchParams.delete", arguments.length, 1);
name = String(name);
let i = 0;
while (i < this.params.length) {
if (this.params[i][0] === name) {
@ -71,6 +76,8 @@ export class URLSearchParams {
* searchParams.getAll('name');
*/
getAll(name: string): string[] {
requiredArguments("URLSearchParams.getAll", arguments.length, 1);
name = String(name);
const values = [];
for (const entry of this.params) {
if (entry[0] === name) {
@ -86,6 +93,8 @@ export class URLSearchParams {
* searchParams.get('name');
*/
get(name: string): string | null {
requiredArguments("URLSearchParams.get", arguments.length, 1);
name = String(name);
for (const entry of this.params) {
if (entry[0] === name) {
return entry[1];
@ -101,6 +110,8 @@ export class URLSearchParams {
* searchParams.has('name');
*/
has(name: string): boolean {
requiredArguments("URLSearchParams.has", arguments.length, 1);
name = String(name);
return this.params.some(entry => entry[0] === name);
}
@ -112,9 +123,12 @@ export class URLSearchParams {
* searchParams.set('name', 'value');
*/
set(name: string, value: string): void {
requiredArguments("URLSearchParams.set", arguments.length, 2);
// If there are any name-value pairs whose name is name, in list,
// set the value of the first such name-value pair to value
// and remove the others.
name = String(name);
let found = false;
let i = 0;
while (i < this.params.length) {
@ -122,13 +136,14 @@ export class URLSearchParams {
if (!found) {
this.params[i][1] = value;
found = true;
i++;
} else {
this.params.splice(i, 1);
continue;
}
}
} else {
i++;
}
}
// Otherwise, append a new name-value pair whose name is name
// and value is value, to list.
@ -163,9 +178,12 @@ export class URLSearchParams {
// tslint:disable-next-line:no-any
thisArg?: any
) {
requiredArguments("URLSearchParams.forEach", arguments.length, 1);
if (typeof thisArg !== "undefined") {
callbackfn = callbackfn.bind(thisArg);
}
for (const [key, value] of this.entries()) {
callbackfn(value, key, this);
}

View file

@ -138,3 +138,41 @@ test(function urlSearchParamsShouldThrowTypeError() {
assertEqual(hasThrown, 2);
});
test(function urlSearchParamsAppendArgumentsCheck() {
const methodRequireOneParam = ["delete", "getAll", "get", "has", "forEach"];
const methodRequireTwoParams = ["append", "set"];
methodRequireOneParam.concat(methodRequireTwoParams).forEach(method => {
const searchParams = new URLSearchParams();
let hasThrown = 0;
try {
searchParams[method]();
hasThrown = 1;
} catch (err) {
if (err instanceof TypeError) {
hasThrown = 2;
} else {
hasThrown = 3;
}
}
assertEqual(hasThrown, 2);
});
methodRequireTwoParams.forEach(method => {
const searchParams = new URLSearchParams();
let hasThrown = 0;
try {
searchParams[method]("foo");
hasThrown = 1;
} catch (err) {
if (err instanceof TypeError) {
hasThrown = 2;
} else {
hasThrown = 3;
}
}
assertEqual(hasThrown, 2);
});
});

View file

@ -137,3 +137,17 @@ export function isTypedArray(x: unknown): x is TypedArray {
export function isObject(o: unknown): o is object {
return o != null && typeof o === "object";
}
// @internal
export function requiredArguments(
name: string,
length: number,
required: number
): void {
if (length < required) {
const errMsg = `${name} requires at least ${required} argument${
required === 1 ? "" : "s"
}, but only ${length} present`;
throw new TypeError(errMsg);
}
}