···
1
-
// These are marked with `Symbol.unscopables` for the Proxy
2
-
const unscopables = {
// Keys that'll always not be included (for Node.js)
···
function safeKey(target: Object, key: string | symbol): string | undefined {
return key !== 'constructor' &&
33
-
key !== 'constructor' &&
26
+
key !== 'prototype' &&
typeof key !== 'symbol' &&
40
-
// Wrap any given target with a Proxy preventing access to unscopables
41
-
function withProxy(target: any) {
33
+
// Wrap any given target with a masking object preventing access to prototype properties
34
+
function mask(target: any) {
(typeof target !== 'function' && typeof target !== 'object')
// If the target isn't a function or object then skip
49
-
typeof Proxy === 'function' &&
50
-
typeof Symbol === 'function' &&
53
-
// Mark hidden keys as unscopable
54
-
target[Symbol.unscopables] = unscopables;
55
-
// Wrap the target in a Proxy that disallows access to some keys
56
-
return new Proxy(target, {
57
-
// Return a value, if it's allowed to be returned, and wrap that value in a proxy recursively
59
-
const key = safeKey(target, _key);
60
-
return key !== undefined ? withProxy(target[key]) : undefined;
63
-
return !!safeKey(target, key);
66
-
deleteProperty: noop,
67
-
defineProperty: noop,
68
-
getOwnPropertyDescriptor: noop,
// Create a stand-in object or function
typeof target === 'function'
75
-
? function (this: any) {
45
+
? (function (this: any) {
return target.apply(this, arguments);
// Copy all known keys over to the stand-in and recursively apply `withProxy`
// Prevent unsafe keys from being accessed
81
-
const keys = ['constructor', 'prototype', '__proto__'].concat(
82
-
Object.getOwnPropertyNames(target)
51
+
const keys = Object.getOwnPropertyNames(target)
for (let i = 0; i < keys.length; i++) {
86
-
Object.defineProperty(standin, key, {
88
-
get: safeKey(target, key)
90
-
return typeof target[key] === 'function' ||
91
-
typeof target[key] === 'object'
92
-
? withProxy(target[key])
54
+
if (key !== 'prototype') {
55
+
Object.defineProperty(standin, key, {
57
+
get: safeKey(target, key)
59
+
return typeof target[key] === 'function' ||
60
+
typeof target[key] === 'object'
68
+
return typeof Object.freeze === 'function'
69
+
? Object.freeze(standin)
let safeGlobal: Record<string | symbol, unknown> | void;
···
for (let i = 0, l = trueGlobalKeys.length; i < l; i++) {
const key = trueGlobalKeys[i];
156
-
safeGlobal[key] = withProxy(vmGlobals[key]);
127
+
safeGlobal[key] = mask(vmGlobals[key]);
// We then reset all globals that are present on `globalThis` directly
···
// It _might_ be safe to expose the Function constructor like this... who knows
safeGlobal!.Function = SafeFunction;
// Lastly, we also disallow certain property accesses on the safe global
166
-
return (safeGlobal = withProxy(safeGlobal!));
137
+
return (safeGlobal = mask(safeGlobal!));