diff --git a/lib/setup-sandbox.js b/lib/setup-sandbox.js index 71afa52..fbfacc4 100644 --- a/lib/setup-sandbox.js +++ b/lib/setup-sandbox.js @@ -21,6 +21,7 @@ const { const { getPrototypeOf: localReflectGetPrototypeOf, apply: localReflectApply, + construct: localReflectConstruct, deleteProperty: localReflectDeleteProperty, has: localReflectHas, defineProperty: localReflectDefineProperty, @@ -432,6 +433,63 @@ if (AsyncGeneratorFunction) { overrideWithProxy(AsyncGeneratorFunction.prototype, 'constructor', AsyncGeneratorFunction, makeCheckFunction(true, true)); } +function makeSafeHandlerArgs(args) { + const sArgs = ensureThis(args); + if (sArgs === args) return args; + const a = []; + for (let i=0; i < sArgs.length; i++) { + localReflectDefineProperty(a, i, { + __proto__: null, + value: sArgs[i], + enumerable: true, + configurable: true, + writable: true + }); + } + return a; +} + +const makeSafeArgs = Object.freeze({ + __proto__: null, + apply(target, thiz, args) { + return localReflectApply(target, thiz, makeSafeHandlerArgs(args)); + }, + construct(target, args, newTarget) { + return localReflectConstruct(target, makeSafeHandlerArgs(args), newTarget); + } +}); + +const proxyHandlerHandler = Object.freeze({ + __proto__: null, + get(target, name, receiver) { + const value = target.handler[name]; + if (typeof value !== 'function') return value; + return new LocalProxy(value, makeSafeArgs); + } +}); + +function wrapProxyHandler(args) { + if (args.length < 2) return args; + const handler = args[1]; + args[1] = new LocalProxy({__proto__: null, handler}, proxyHandlerHandler); + return args; +} + +const proxyHandler = Object.freeze({ + __proto__: null, + apply(target, thiz, args) { + return localReflectApply(target, thiz, wrapProxyHandler(args)); + }, + construct(target, args, newTarget) { + return localReflectConstruct(target, wrapProxyHandler(args), newTarget); + } +}); + +const proxiedProxy = new LocalProxy(LocalProxy, proxyHandler); + +overrideWithProxy(LocalProxy, 'revocable', LocalProxy.revocable, proxyHandler); + +global.Proxy = proxiedProxy; global.Function = proxiedFunction; global.eval = new LocalProxy(localEval, EvalHandler);