From 4ec213b0aa1aeb1b3220ef4b65d8b94f54ddc7b9 Mon Sep 17 00:00:00 2001 From: Garcia Date: Fri, 2 Sep 2022 08:55:44 -0700 Subject: [PATCH] fix(ext/timers): create primordial `eval` (#15110) --- cli/tests/unit/timers_test.ts | 21 +++++++++++++++++++++ core/00_primordials.js | 5 +++++ ext/web/02_timers.js | 5 ++--- 3 files changed, 28 insertions(+), 3 deletions(-) diff --git a/cli/tests/unit/timers_test.ts b/cli/tests/unit/timers_test.ts index e6901a42c5..735e53e0fd 100644 --- a/cli/tests/unit/timers_test.ts +++ b/cli/tests/unit/timers_test.ts @@ -84,6 +84,27 @@ Deno.test(async function timeoutEvalNoScopeLeak() { Reflect.deleteProperty(global, "globalPromise"); }); +Deno.test(async function evalPrimordial() { + const global = globalThis as unknown as { + globalPromise: ReturnType; + }; + global.globalPromise = deferred(); + const originalEval = globalThis.eval; + let wasCalled = false; + globalThis.eval = (argument) => { + wasCalled = true; + return originalEval(argument); + }; + setTimeout( + "globalThis.globalPromise.resolve();" as unknown as () => void, + 0, + ); + await global.globalPromise; + assert(!wasCalled); + Reflect.deleteProperty(global, "globalPromise"); + globalThis.eval = originalEval; +}); + Deno.test(async function timeoutArgs() { const promise = deferred(); const arg = 1; diff --git a/core/00_primordials.js b/core/00_primordials.js index 4ca7ce0730..843eb8b294 100644 --- a/core/00_primordials.js +++ b/core/00_primordials.js @@ -468,6 +468,11 @@ queueMicrotask = value; }; + // Renaming from `eval` is necessary because otherwise it would perform direct + // evaluation, allowing user-land access to local variables. + // This is because the identifier `eval` is somewhat treated as a keyword + primordials.indirectEval = eval; + ObjectSetPrototypeOf(primordials, null); ObjectFreeze(primordials); diff --git a/ext/web/02_timers.js b/ext/web/02_timers.js index f703120e60..6cbc706e67 100644 --- a/ext/web/02_timers.js +++ b/ext/web/02_timers.js @@ -21,6 +21,7 @@ SafeArrayIterator, SymbolFor, TypeError, + indirectEval, } = window.__bootstrap.primordials; const { webidl } = window.__bootstrap; const { reportException } = window.__bootstrap.event; @@ -155,9 +156,7 @@ reportException(error); } } else { - // TODO(@andreubotella): eval doesn't seem to have a primordial, but - // it can be redefined in the global scope. - (0, eval)(callback); + indirectEval(callback); } if (repeat) {