Skip to content

Commit

Permalink
feat(node): add vm.runInThisContext (#1747)
Browse files Browse the repository at this point in the history
  • Loading branch information
kt3k authored Dec 23, 2021
1 parent 1f7beb1 commit 956c36a
Show file tree
Hide file tree
Showing 5 changed files with 164 additions and 20 deletions.
3 changes: 2 additions & 1 deletion node/_tools/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -383,7 +383,8 @@
"test-util-inspect.js",
"test-util-isDeepStrictEqual.js",
"test-util-types.js",
"test-util.js"
"test-util.js",
"test-vm-static-this.js"
]
},
"windowsIgnore": {
Expand Down
84 changes: 84 additions & 0 deletions node/_tools/suites/common/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,89 @@ function platformTimeout(ms) {

let localhostIPv4 = null;

let knownGlobals = [
atob,
btoa,
clearImmediate,
clearInterval,
clearTimeout,
global,
setImmediate,
setInterval,
setTimeout,
queueMicrotask,
Deno,
dispatchEvent,
addEventListener,
removeEventListener,
AbortSignal,
crypto,
fetch,
location,
navigator,
close,
closed,
alert,
confirm,
prompt,
localStorage,
sessionStorage,
onload,
onunload,
getParent,
];

if (global.AbortController)
knownGlobals.push(global.AbortController);

if (global.gc) {
knownGlobals.push(global.gc);
}

if (global.performance) {
knownGlobals.push(global.performance);
}
if (global.PerformanceMark) {
knownGlobals.push(global.PerformanceMark);
}
if (global.PerformanceMeasure) {
knownGlobals.push(global.PerformanceMeasure);
}

if (global.structuredClone) {
knownGlobals.push(global.structuredClone);
}

function allowGlobals(...allowlist) {
knownGlobals = knownGlobals.concat(allowlist);
}

if (process.env.NODE_TEST_KNOWN_GLOBALS !== '0') {
if (process.env.NODE_TEST_KNOWN_GLOBALS) {
const knownFromEnv = process.env.NODE_TEST_KNOWN_GLOBALS.split(',');
allowGlobals(...knownFromEnv);
}

function leakedGlobals() {
const leaked = [];

for (const val in global) {
if (!knownGlobals.includes(global[val])) {
leaked.push(val);
}
}

return leaked;
}

process.on('exit', function() {
const leaked = leakedGlobals();
if (leaked.length > 0) {
assert.fail(`Unexpected global(s) found: ${leaked.join(', ')}`);
}
});
}

function _expectWarning(name, expected, code) {
if (typeof expected === 'string') {
expected = [[expected, code]];
Expand Down Expand Up @@ -260,6 +343,7 @@ function skip(msg) {
}

module.exports = {
allowGlobals,
expectsError,
expectWarning,
invalidArgTypeHelper,
Expand Down
72 changes: 72 additions & 0 deletions node/_tools/suites/parallel/test-vm-static-this.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
// deno-fmt-ignore-file
// deno-lint-ignore-file

// Copyright Joyent and Node contributors. All rights reserved. MIT license.
// Taken from Node 16.13.0
// This file is automatically generated by "node/_tools/setup.ts". Do not modify this file manually

// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.

/* eslint-disable strict */
const common = require('../common');
const assert = require('assert');
const vm = require('vm');

// Run a string
const result = vm.runInThisContext('\'passed\';');
assert.strictEqual(result, 'passed');

// thrown error
assert.throws(function() {
vm.runInThisContext('throw new Error(\'test\');');
}, /test/);

global.hello = 5;
vm.runInThisContext('hello = 2');
assert.strictEqual(global.hello, 2);


// pass values
const code = 'foo = 1;' +
'bar = 2;' +
'if (typeof baz !== \'undefined\')' +
'throw new Error(\'test fail\');';
global.foo = 2;
global.obj = { foo: 0, baz: 3 };
/* eslint-disable no-unused-vars */
const baz = vm.runInThisContext(code);
/* eslint-enable no-unused-vars */
assert.strictEqual(global.obj.foo, 0);
assert.strictEqual(global.bar, 2);
assert.strictEqual(global.foo, 1);

// call a function
global.f = function() { global.foo = 100; };
vm.runInThisContext('f()');
assert.strictEqual(global.foo, 100);

common.allowGlobals(
global.hello,
global.foo,
global.obj,
global.f
);
11 changes: 6 additions & 5 deletions node/vm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,13 @@
import { notImplemented } from "./_utils.ts";

export class Script {
code: string;
constructor(code: string, _options = {}) {
code = `${code}`;
this.code = `${code}`;
}

runInThisContext(_options: any) {
notImplemented();
return eval.call(globalThis, this.code);
}

runInContext(_contextifiedObject: any, _options: any) {
Expand Down Expand Up @@ -51,10 +52,10 @@ export function runInNewContext(
}

export function runInThisContext(
_code: string,
_options: any,
code: string,
options: any,
) {
notImplemented();
return createScript(code, options).runInThisContext(options);
}

export function isContext(_maybeContext: any) {
Expand Down
14 changes: 0 additions & 14 deletions node/vm_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,6 @@ Deno.test("createScript", function () {
const script = vm.createScript("foo", {});
assert(script instanceof vm.Script);

assertThrows(
() => {
script.runInThisContext({});
},
Error,
"Not implemented",
);
assertThrows(
() => {
script.runInContext({}, {});
Expand Down Expand Up @@ -60,13 +53,6 @@ Deno.test({
Error,
"Not implemented",
);
assertThrows(
() => {
vm.runInThisContext("", {});
},
Error,
"Not implemented",
);
assertThrows(
() => {
vm.isContext({});
Expand Down

0 comments on commit 956c36a

Please sign in to comment.