From a3a78ce6f540900ae9f069cfb55a9a0d9a841949 Mon Sep 17 00:00:00 2001 From: Jack Works Date: Sat, 28 Sep 2019 10:49:40 +0800 Subject: [PATCH] fix: getPrototypeOf trap get called in safari --- src/scopeHandler.js | 12 ++++++++++-- test/module/scopeHandler.js | 5 +++-- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/scopeHandler.js b/src/scopeHandler.js index 2bfae5e..db60667 100644 --- a/src/scopeHandler.js +++ b/src/scopeHandler.js @@ -8,7 +8,7 @@ import { throwTantrum } from './utilities'; */ const alwaysThrowHandler = new Proxy(freeze({}), { get(target, prop) { - throwTantrum(`unexpected scope handler trap called: ${prop}`); + throwTantrum(`unexpected scope handler trap called: ${String(prop)}`); } }); @@ -25,6 +25,8 @@ const alwaysThrowHandler = new Proxy(freeze({}), { * - route all other property lookups at the safeGlobal. * - hide the unsafeGlobal which lives on the scope chain above the 'with'. * - ensure the Proxy invariants despite some global properties being frozen. + * + * @returns {ProxyHandler & Record} */ export function createScopeHandler(unsafeRec, safeGlobal, sloppyGlobals) { const { unsafeGlobal, unsafeEval } = unsafeRec; @@ -79,7 +81,6 @@ export function createScopeHandler(unsafeRec, safeGlobal, sloppyGlobals) { return undefined; }, - // eslint-disable-next-line class-methods-use-this set(target, prop, value) { // todo: allow modifications when target.hasOwnProperty(prop) and it // is writable, assuming we've already rejected overlap (see @@ -134,6 +135,13 @@ export function createScopeHandler(unsafeRec, safeGlobal, sloppyGlobals) { } return false; + }, + + // note: this is likely a bug of safari + // https://bugs.webkit.org/show_bug.cgi?id=195534 + + getPrototypeOf() { + return null; } }; } diff --git a/test/module/scopeHandler.js b/test/module/scopeHandler.js index cf7c1e5..af6f9cb 100644 --- a/test/module/scopeHandler.js +++ b/test/module/scopeHandler.js @@ -9,7 +9,9 @@ test('scope handler traps', t => { const handler = createScopeHandler({}); - ['has', 'get', 'set'].forEach(trap => t.doesNotThrow(() => handler[trap])); + ['has', 'get', 'set', 'getPrototypeOf'].forEach(trap => + t.doesNotThrow(() => handler[trap]) + ); [ 'apply', @@ -17,7 +19,6 @@ test('scope handler traps', t => { 'defineProperty', 'delteProperty', 'getOwnProperty', - 'getPrototypeOf', 'isExtensible', 'ownKeys', 'preventExtensions',