Skip to content

Commit 5b9187e

Browse files
committed
vm: DONT_CONTEXTIFY when no contextObject set
When `contextObject` is not passed in `vm.createContext`, do not contextify by default. This reduces the chance that the script semantics are broken by the interceptors.
1 parent 38647b3 commit 5b9187e

File tree

3 files changed

+53
-2
lines changed

3 files changed

+53
-2
lines changed

lib/vm.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,7 @@ function getContextOptions(options) {
222222
}
223223

224224
let defaultContextNameIndex = 1;
225-
function createContext(contextObject = {}, options = kEmptyObject) {
225+
function createContext(contextObject = vm_context_no_contextify, options = kEmptyObject) {
226226
if (contextObject !== vm_context_no_contextify && isContext(contextObject)) {
227227
return contextObject;
228228
}

test/known_issues/test-vm-function-declaration-uses-define.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ const common = require('../common');
99
const vm = require('vm');
1010
const assert = require('assert');
1111

12-
const ctx = vm.createContext();
12+
const ctx = vm.createContext({});
1313
Object.defineProperty(ctx, 'x', {
1414
enumerable: true,
1515
configurable: true,
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
'use strict';
2+
require('../common');
3+
const assert = require('assert');
4+
5+
const vm = require('vm');
6+
7+
// Declared with `var`.
8+
{
9+
const ctx = vm.createContext();
10+
vm.runInContext(`"use strict"; var x; x = 42;`, ctx);
11+
assert.strictEqual(ctx.x, 42);
12+
}
13+
14+
// Define on `globalThis`.
15+
{
16+
const ctx = vm.createContext();
17+
vm.runInContext(`
18+
"use strict";
19+
Object.defineProperty(globalThis, "x", {
20+
configurable: true,
21+
value: 42,
22+
});
23+
`, ctx);
24+
const ret = vm.runInContext(`"use strict"; x`, ctx);
25+
assert.strictEqual(ret, 42);
26+
assert.strictEqual(ctx.x, 42);
27+
}
28+
29+
// Set on globalThis.
30+
{
31+
const ctx = vm.createContext();
32+
vm.runInContext(`"use strict"; globalThis.x = 42`, ctx);
33+
const ret = vm.runInContext(`"use strict"; x`, ctx);
34+
assert.strictEqual(ret, 42);
35+
assert.strictEqual(ctx.x, 42);
36+
}
37+
38+
// Set on context.
39+
// Should throw a ReferenceError when a variable is not defined in strict-mode.
40+
assert.throws(() => vm.runInNewContext(`"use strict"; x = 42`),
41+
/ReferenceError: x is not defined/);
42+
43+
// Known issue since V8 14.6.
44+
// When the context is a "contextified" object, ReferenceError can not be thrown.
45+
// TODO(legendecas): https://github.com/nodejs/node/pull/61898#issuecomment-4142811603
46+
// Refs: https://chromium-review.googlesource.com/c/v8/v8/+/7474608
47+
{
48+
const ctx = vm.createContext({});
49+
assert.throws(() => vm.runInContext(`"use strict"; x = 42`, ctx),
50+
/ReferenceError: x is not defined/);
51+
}

0 commit comments

Comments
 (0)