Skip to content

Commit

Permalink
Make Deno/Deno.core not deletable/writable (denoland#2153)
Browse files Browse the repository at this point in the history
  • Loading branch information
kevinkassimo authored and ry committed Apr 20, 2019
1 parent 0796a8f commit c8db224
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 2 deletions.
5 changes: 3 additions & 2 deletions js/globals.ts
Expand Up @@ -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";
Expand All @@ -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
Expand All @@ -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
Expand Down
44 changes: 44 additions & 0 deletions js/globals_test.ts
Expand Up @@ -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);
});
5 changes: 5 additions & 0 deletions js/os.ts
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}
15 changes: 15 additions & 0 deletions js/util.ts
Expand Up @@ -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,
Expand Down

0 comments on commit c8db224

Please sign in to comment.