summaryrefslogtreecommitdiff
path: root/js
diff options
context:
space:
mode:
authorKevin (Kun) "Kassimo" Qian <kevinkassimo@gmail.com>2019-04-19 17:39:54 -0700
committerRyan Dahl <ry@tinyclouds.org>2019-04-19 20:39:54 -0400
commitc8db224efed08d7722c9951cde048d731db050d3 (patch)
treeb492275744af8dfae9977ef8309925e725daba09 /js
parent0796a8f2f75005df95ef6115a4bdf6dd66e58dc3 (diff)
Make Deno/Deno.core not deletable/writable (#2153)
Diffstat (limited to 'js')
-rw-r--r--js/globals.ts5
-rw-r--r--js/globals_test.ts44
-rw-r--r--js/os.ts5
-rw-r--r--js/util.ts15
4 files changed, 67 insertions, 2 deletions
diff --git a/js/globals.ts b/js/globals.ts
index fae14773b..6ebf3ddfd 100644
--- a/js/globals.ts
+++ b/js/globals.ts
@@ -5,7 +5,7 @@
// library.
// Modules which will make up part of the global public API surface should be
-// imported as namespaces, so when the runtime tpye library is generated they
+// imported as namespaces, so when the runtime type library is generated they
// can be expressed as a namespace in the type library.
import { window } from "./window";
import * as blob from "./blob";
@@ -29,6 +29,7 @@ import * as performanceUtil from "./performance";
// These imports are not exposed and therefore are fine to just import the
// symbols required.
import { core } from "./core";
+import { immutableDefine } from "./util";
// During the build process, augmentations to the variable `window` in this
// file are tracked and created as part of default library that is built into
@@ -44,7 +45,7 @@ window.window = window;
// This is the Deno namespace, it is handled differently from other window
// properties when building the runtime type library, as the whole module
// is flattened into a single namespace.
-window.Deno = deno;
+immutableDefine(window, "Deno", deno);
Object.freeze(window.Deno);
// ref https://console.spec.whatwg.org/#console-namespace
diff --git a/js/globals_test.ts b/js/globals_test.ts
index 60b560134..4937e6c9a 100644
--- a/js/globals_test.ts
+++ b/js/globals_test.ts
@@ -33,3 +33,47 @@ test(function DenoNamespaceIsFrozen() {
test(function webAssemblyExists() {
assert(typeof WebAssembly.compile === "function");
});
+
+test(function DenoNamespaceImmutable() {
+ const denoCopy = window.Deno;
+ try {
+ // @ts-ignore
+ Deno = 1;
+ } catch {}
+ assert(denoCopy === Deno);
+ try {
+ // @ts-ignore
+ window.Deno = 1;
+ } catch {}
+ assert(denoCopy === Deno);
+ try {
+ delete window.Deno;
+ } catch {}
+ assert(denoCopy === Deno);
+
+ const { readFile } = Deno;
+ try {
+ // @ts-ignore
+ Deno.readFile = 1;
+ } catch {}
+ assert(readFile === Deno.readFile);
+ try {
+ delete window.Deno.readFile;
+ } catch {}
+ assert(readFile === Deno.readFile);
+
+ // @ts-ignore
+ const { print } = Deno.core;
+ try {
+ // @ts-ignore
+ Deno.core.print = 1;
+ } catch {}
+ // @ts-ignore
+ assert(print === Deno.core.print);
+ try {
+ // @ts-ignore
+ delete Deno.core.print;
+ } catch {}
+ // @ts-ignore
+ assert(print === Deno.core.print);
+});
diff --git a/js/os.ts b/js/os.ts
index 86a2c4943..5dc5521b4 100644
--- a/js/os.ts
+++ b/js/os.ts
@@ -6,6 +6,7 @@ import * as flatbuffers from "./flatbuffers";
import { TextDecoder } from "./text_encoding";
import { assert } from "./util";
import * as util from "./util";
+import { window } from "./window";
/** The current process id of the runtime. */
export let pid: number;
@@ -168,5 +169,9 @@ export function start(source?: string): msg.StartRes {
setGlobals(startResMsg.pid(), startResMsg.noColor(), startResMsg.execPath()!);
+ // Deno.core could ONLY be safely frozen here (not in globals.ts)
+ // since shared_queue.js will modify core properties.
+ Object.freeze(window.Deno.core);
+
return startResMsg;
}
diff --git a/js/util.ts b/js/util.ts
index b81b96aca..348e36a1f 100644
--- a/js/util.ts
+++ b/js/util.ts
@@ -131,6 +131,21 @@ export function requiredArguments(
}
}
+// @internal
+export function immutableDefine(
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ o: any,
+ p: string | number | symbol,
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ value: any
+): void {
+ Object.defineProperty(o, p, {
+ value,
+ configurable: false,
+ writable: false
+ });
+}
+
// Returns values from a WeakMap to emulate private properties in JavaScript
export function getPrivateValue<
K extends object,