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:
parent
9909e8a759
commit
7d0e1050d3
3 changed files with 73 additions and 3 deletions
|
@ -1,3 +1,5 @@
|
||||||
|
import { requiredArguments } from "./util";
|
||||||
|
|
||||||
// Copyright 2018 the Deno authors. All rights reserved. MIT license.
|
// Copyright 2018 the Deno authors. All rights reserved. MIT license.
|
||||||
export class URLSearchParams {
|
export class URLSearchParams {
|
||||||
private params: Array<[string, string]> = [];
|
private params: Array<[string, string]> = [];
|
||||||
|
@ -46,7 +48,8 @@ export class URLSearchParams {
|
||||||
* searchParams.append('name', 'second');
|
* searchParams.append('name', 'second');
|
||||||
*/
|
*/
|
||||||
append(name: string, value: string): void {
|
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,
|
/** Deletes the given search parameter and its associated value,
|
||||||
|
@ -55,6 +58,8 @@ export class URLSearchParams {
|
||||||
* searchParams.delete('name');
|
* searchParams.delete('name');
|
||||||
*/
|
*/
|
||||||
delete(name: string): void {
|
delete(name: string): void {
|
||||||
|
requiredArguments("URLSearchParams.delete", arguments.length, 1);
|
||||||
|
name = String(name);
|
||||||
let i = 0;
|
let i = 0;
|
||||||
while (i < this.params.length) {
|
while (i < this.params.length) {
|
||||||
if (this.params[i][0] === name) {
|
if (this.params[i][0] === name) {
|
||||||
|
@ -71,6 +76,8 @@ export class URLSearchParams {
|
||||||
* searchParams.getAll('name');
|
* searchParams.getAll('name');
|
||||||
*/
|
*/
|
||||||
getAll(name: string): string[] {
|
getAll(name: string): string[] {
|
||||||
|
requiredArguments("URLSearchParams.getAll", arguments.length, 1);
|
||||||
|
name = String(name);
|
||||||
const values = [];
|
const values = [];
|
||||||
for (const entry of this.params) {
|
for (const entry of this.params) {
|
||||||
if (entry[0] === name) {
|
if (entry[0] === name) {
|
||||||
|
@ -86,6 +93,8 @@ export class URLSearchParams {
|
||||||
* searchParams.get('name');
|
* searchParams.get('name');
|
||||||
*/
|
*/
|
||||||
get(name: string): string | null {
|
get(name: string): string | null {
|
||||||
|
requiredArguments("URLSearchParams.get", arguments.length, 1);
|
||||||
|
name = String(name);
|
||||||
for (const entry of this.params) {
|
for (const entry of this.params) {
|
||||||
if (entry[0] === name) {
|
if (entry[0] === name) {
|
||||||
return entry[1];
|
return entry[1];
|
||||||
|
@ -101,6 +110,8 @@ export class URLSearchParams {
|
||||||
* searchParams.has('name');
|
* searchParams.has('name');
|
||||||
*/
|
*/
|
||||||
has(name: string): boolean {
|
has(name: string): boolean {
|
||||||
|
requiredArguments("URLSearchParams.has", arguments.length, 1);
|
||||||
|
name = String(name);
|
||||||
return this.params.some(entry => entry[0] === name);
|
return this.params.some(entry => entry[0] === name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,9 +123,12 @@ export class URLSearchParams {
|
||||||
* searchParams.set('name', 'value');
|
* searchParams.set('name', 'value');
|
||||||
*/
|
*/
|
||||||
set(name: string, value: string): void {
|
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,
|
// 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
|
// set the value of the first such name-value pair to value
|
||||||
// and remove the others.
|
// and remove the others.
|
||||||
|
name = String(name);
|
||||||
let found = false;
|
let found = false;
|
||||||
let i = 0;
|
let i = 0;
|
||||||
while (i < this.params.length) {
|
while (i < this.params.length) {
|
||||||
|
@ -122,13 +136,14 @@ export class URLSearchParams {
|
||||||
if (!found) {
|
if (!found) {
|
||||||
this.params[i][1] = value;
|
this.params[i][1] = value;
|
||||||
found = true;
|
found = true;
|
||||||
|
i++;
|
||||||
} else {
|
} else {
|
||||||
this.params.splice(i, 1);
|
this.params.splice(i, 1);
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Otherwise, append a new name-value pair whose name is name
|
// Otherwise, append a new name-value pair whose name is name
|
||||||
// and value is value, to list.
|
// and value is value, to list.
|
||||||
|
@ -163,9 +178,12 @@ export class URLSearchParams {
|
||||||
// tslint:disable-next-line:no-any
|
// tslint:disable-next-line:no-any
|
||||||
thisArg?: any
|
thisArg?: any
|
||||||
) {
|
) {
|
||||||
|
requiredArguments("URLSearchParams.forEach", arguments.length, 1);
|
||||||
|
|
||||||
if (typeof thisArg !== "undefined") {
|
if (typeof thisArg !== "undefined") {
|
||||||
callbackfn = callbackfn.bind(thisArg);
|
callbackfn = callbackfn.bind(thisArg);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const [key, value] of this.entries()) {
|
for (const [key, value] of this.entries()) {
|
||||||
callbackfn(value, key, this);
|
callbackfn(value, key, this);
|
||||||
}
|
}
|
||||||
|
|
|
@ -138,3 +138,41 @@ test(function urlSearchParamsShouldThrowTypeError() {
|
||||||
|
|
||||||
assertEqual(hasThrown, 2);
|
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);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
14
js/util.ts
14
js/util.ts
|
@ -137,3 +137,17 @@ export function isTypedArray(x: unknown): x is TypedArray {
|
||||||
export function isObject(o: unknown): o is object {
|
export function isObject(o: unknown): o is object {
|
||||||
return o != null && typeof o === "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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue