mirror of
https://github.com/denoland/deno.git
synced 2024-12-24 16:19:12 -05:00
fix(cli/rt): make some web API constructors illegal at runtime (#7468)
This commit is contained in:
parent
79e5b57663
commit
aaa5e6613a
9 changed files with 106 additions and 15 deletions
6
cli/dts/lib.deno.unstable.d.ts
vendored
6
cli/dts/lib.deno.unstable.d.ts
vendored
|
@ -130,11 +130,11 @@ declare namespace Deno {
|
|||
*/
|
||||
export function osRelease(): string;
|
||||
|
||||
/** **Unstable** new API. yet to be vetted.
|
||||
/** **Unstable** new API. yet to be vetted.
|
||||
*
|
||||
* Displays the total amount of free and used physical and swap memory in the
|
||||
* system, as well as the buffers and caches used by the kernel.
|
||||
*
|
||||
*
|
||||
* This is similar to the `free` command in Linux
|
||||
*
|
||||
* ```ts
|
||||
|
@ -1113,7 +1113,7 @@ declare namespace Deno {
|
|||
/** see: https://w3c.github.io/permissions/#permissionstatus */
|
||||
export class PermissionStatus {
|
||||
state: PermissionState;
|
||||
constructor(state: PermissionState);
|
||||
constructor();
|
||||
}
|
||||
|
||||
/** **UNSTABLE**: New API, yet to be vetted. Additional consideration is still
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
((window) => {
|
||||
const illegalConstructorKey = Symbol("illegalConstructorKey");
|
||||
|
||||
function isInvalidDate(x) {
|
||||
return isNaN(x.getTime());
|
||||
}
|
||||
|
@ -146,6 +148,7 @@
|
|||
}
|
||||
|
||||
window.__bootstrap.webUtil = {
|
||||
illegalConstructorKey,
|
||||
isInvalidDate,
|
||||
requiredArguments,
|
||||
immutableDefine,
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
((window) => {
|
||||
const { opNow } = window.__bootstrap.timers;
|
||||
const { cloneValue } = window.__bootstrap.webUtil;
|
||||
const { cloneValue, illegalConstructorKey } = window.__bootstrap.webUtil;
|
||||
|
||||
const customInspect = Symbol.for("Deno.customInspect");
|
||||
let performanceEntries = [];
|
||||
|
@ -74,7 +74,11 @@
|
|||
entryType,
|
||||
startTime,
|
||||
duration,
|
||||
key,
|
||||
) {
|
||||
if (key != illegalConstructorKey) {
|
||||
throw new TypeError("Illegal constructor.");
|
||||
}
|
||||
this.#name = name;
|
||||
this.#entryType = entryType;
|
||||
this.#startTime = startTime;
|
||||
|
@ -110,7 +114,7 @@
|
|||
name,
|
||||
{ detail = null, startTime = now() } = {},
|
||||
) {
|
||||
super(name, "mark", startTime, 0);
|
||||
super(name, "mark", startTime, 0, illegalConstructorKey);
|
||||
if (startTime < 0) {
|
||||
throw new TypeError("startTime cannot be negative");
|
||||
}
|
||||
|
@ -152,8 +156,12 @@
|
|||
startTime,
|
||||
duration,
|
||||
detail = null,
|
||||
key,
|
||||
) {
|
||||
super(name, "measure", startTime, duration);
|
||||
if (key != illegalConstructorKey) {
|
||||
throw new TypeError("Illegal constructor.");
|
||||
}
|
||||
super(name, "measure", startTime, duration, illegalConstructorKey);
|
||||
this.#detail = cloneValue(detail);
|
||||
}
|
||||
|
||||
|
@ -177,6 +185,12 @@
|
|||
}
|
||||
|
||||
class Performance {
|
||||
constructor(key) {
|
||||
if (key != illegalConstructorKey) {
|
||||
throw new TypeError("Illegal constructor.");
|
||||
}
|
||||
}
|
||||
|
||||
clearMarks(markName) {
|
||||
if (markName == null) {
|
||||
performanceEntries = performanceEntries.filter(
|
||||
|
@ -302,6 +316,7 @@
|
|||
typeof startOrMeasureOptions === "object"
|
||||
? startOrMeasureOptions.detail ?? null
|
||||
: null,
|
||||
illegalConstructorKey,
|
||||
);
|
||||
performanceEntries.push(entry);
|
||||
return entry;
|
||||
|
@ -312,10 +327,13 @@
|
|||
}
|
||||
}
|
||||
|
||||
const performance = new Performance(illegalConstructorKey);
|
||||
|
||||
window.__bootstrap.performance = {
|
||||
PerformanceEntry,
|
||||
PerformanceMark,
|
||||
PerformanceMeasure,
|
||||
Performance,
|
||||
performance,
|
||||
};
|
||||
})(this);
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
((window) => {
|
||||
const core = window.Deno.core;
|
||||
const { illegalConstructorKey } = window.__bootstrap.webUtil;
|
||||
|
||||
function opQuery(desc) {
|
||||
return core.jsonOpSync("op_query_permission", desc).state;
|
||||
|
@ -16,30 +17,45 @@
|
|||
}
|
||||
|
||||
class PermissionStatus {
|
||||
constructor(state) {
|
||||
constructor(state, key) {
|
||||
if (key != illegalConstructorKey) {
|
||||
throw new TypeError("Illegal constructor.");
|
||||
}
|
||||
this.state = state;
|
||||
}
|
||||
// TODO(kt3k): implement onchange handler
|
||||
}
|
||||
|
||||
class Permissions {
|
||||
constructor(key) {
|
||||
if (key != illegalConstructorKey) {
|
||||
throw new TypeError("Illegal constructor.");
|
||||
}
|
||||
}
|
||||
|
||||
query(desc) {
|
||||
const state = opQuery(desc);
|
||||
return Promise.resolve(new PermissionStatus(state));
|
||||
return Promise.resolve(
|
||||
new PermissionStatus(state, illegalConstructorKey),
|
||||
);
|
||||
}
|
||||
|
||||
revoke(desc) {
|
||||
const state = opRevoke(desc);
|
||||
return Promise.resolve(new PermissionStatus(state));
|
||||
return Promise.resolve(
|
||||
new PermissionStatus(state, illegalConstructorKey),
|
||||
);
|
||||
}
|
||||
|
||||
request(desc) {
|
||||
const state = opRequest(desc);
|
||||
return Promise.resolve(new PermissionStatus(state));
|
||||
return Promise.resolve(
|
||||
new PermissionStatus(state, illegalConstructorKey),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const permissions = new Permissions();
|
||||
const permissions = new Permissions(illegalConstructorKey);
|
||||
|
||||
window.__bootstrap.permissions = {
|
||||
permissions,
|
||||
|
|
|
@ -235,7 +235,7 @@ delete Object.prototype.__proto__;
|
|||
crypto: util.readOnly(crypto),
|
||||
dispatchEvent: util.readOnly(EventTarget.prototype.dispatchEvent),
|
||||
fetch: util.writable(fetch.fetch),
|
||||
performance: util.writable(new performance.Performance()),
|
||||
performance: util.writable(performance.performance),
|
||||
removeEventListener: util.readOnly(
|
||||
EventTarget.prototype.removeEventListener,
|
||||
),
|
||||
|
|
|
@ -3,6 +3,7 @@ import {
|
|||
unitTest,
|
||||
assert,
|
||||
assertEquals,
|
||||
assertThrows,
|
||||
createResolvable,
|
||||
} from "./test_util.ts";
|
||||
|
||||
|
@ -64,3 +65,19 @@ unitTest(function performanceMeasure() {
|
|||
}, 100);
|
||||
});
|
||||
});
|
||||
|
||||
unitTest(function performanceIllegalConstructor() {
|
||||
assertThrows(() => new Performance(), TypeError, "Illegal constructor.");
|
||||
});
|
||||
|
||||
unitTest(function performanceEntryIllegalConstructor() {
|
||||
assertThrows(() => new PerformanceEntry(), TypeError, "Illegal constructor.");
|
||||
});
|
||||
|
||||
unitTest(function performanceMeasureIllegalConstructor() {
|
||||
assertThrows(
|
||||
() => new PerformanceMeasure(),
|
||||
TypeError,
|
||||
"Illegal constructor.",
|
||||
);
|
||||
});
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
|
||||
import { unitTest, assertThrowsAsync } from "./test_util.ts";
|
||||
import { unitTest, assertThrows, assertThrowsAsync } from "./test_util.ts";
|
||||
|
||||
unitTest(async function permissionInvalidName(): Promise<void> {
|
||||
await assertThrowsAsync(async () => {
|
||||
|
@ -13,3 +13,15 @@ unitTest(async function permissionNetInvalidUrl(): Promise<void> {
|
|||
await Deno.permissions.query({ name: "net", url: ":" });
|
||||
}, URIError);
|
||||
});
|
||||
|
||||
unitTest(function permissionsIllegalConstructor() {
|
||||
assertThrows(() => new Deno.Permissions(), TypeError, "Illegal constructor.");
|
||||
});
|
||||
|
||||
unitTest(function permissionStatusIllegalConstructor() {
|
||||
assertThrows(
|
||||
() => new Deno.PermissionStatus(),
|
||||
TypeError,
|
||||
"Illegal constructor.",
|
||||
);
|
||||
});
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
const signalAbort = Symbol("signalAbort");
|
||||
const remove = Symbol("remove");
|
||||
|
||||
const illegalConstructorKey = Symbol("illegalConstructorKey");
|
||||
|
||||
class AbortSignal extends EventTarget {
|
||||
#aborted = false;
|
||||
#abortAlgorithms = new Set();
|
||||
|
@ -29,7 +31,10 @@
|
|||
this.#abortAlgorithms.delete(algorithm);
|
||||
}
|
||||
|
||||
constructor() {
|
||||
constructor(key) {
|
||||
if (key != illegalConstructorKey) {
|
||||
throw new TypeError("Illegal constructor.");
|
||||
}
|
||||
super();
|
||||
this.onabort = null;
|
||||
this.addEventListener("abort", (evt) => {
|
||||
|
@ -50,7 +55,7 @@
|
|||
}
|
||||
|
||||
class AbortController {
|
||||
#signal = new AbortSignal();
|
||||
#signal = new AbortSignal(illegalConstructorKey);
|
||||
|
||||
get signal() {
|
||||
return this.#signal;
|
||||
|
|
|
@ -9,6 +9,19 @@ function assertEquals(left, right) {
|
|||
assert(left === right);
|
||||
}
|
||||
|
||||
function assertThrows(fn) {
|
||||
let error = null;
|
||||
try {
|
||||
fn();
|
||||
} catch (error_) {
|
||||
error = error_;
|
||||
}
|
||||
if (error == null) {
|
||||
throw new Error("Didn't throw.");
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
function basicAbortController() {
|
||||
controller = new AbortController();
|
||||
assert(controller);
|
||||
|
@ -64,12 +77,19 @@ function controllerHasProperToString() {
|
|||
assertEquals(actual, "[object AbortController]");
|
||||
}
|
||||
|
||||
function abortSignalIllegalConstructor() {
|
||||
const error = assertThrows(() => new AbortSignal());
|
||||
assert(error instanceof TypeError);
|
||||
assertEquals(error.message, "Illegal constructor.");
|
||||
}
|
||||
|
||||
function main() {
|
||||
basicAbortController();
|
||||
signalCallsOnabort();
|
||||
signalEventListener();
|
||||
onlyAbortsOnce();
|
||||
controllerHasProperToString();
|
||||
abortSignalIllegalConstructor();
|
||||
}
|
||||
|
||||
main();
|
||||
|
|
Loading…
Reference in a new issue