0
0
mirror of https://github.com/nodejs/node.git synced 2024-11-21 21:19:50 +01:00
nodejs/test/parallel/test-vm-context-dont-contextify.js
Antoine du Hamel 7ecc48d061
test: fix test-vm-context-dont-contextify when path contains a space
Because of the double encoding, the test would fail as soon as the path
contains a space or any other char that's already encoded by
`pathToFileURL`.

PR-URL: https://github.com/nodejs/node/pull/55026
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: Richard Lau <rlau@redhat.com>
Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
2024-09-22 10:01:41 +00:00

186 lines
7.3 KiB
JavaScript

'use strict';
// Check vm.constants.DONT_CONTEXTIFY works.
const common = require('../common');
const assert = require('assert');
const vm = require('vm');
const fixtures = require('../common/fixtures');
{
// Check identity of the returned object.
const context = vm.createContext(vm.constants.DONT_CONTEXTIFY);
// The globalThis in the new context should be reference equal to the returned object.
assert.strictEqual(vm.runInContext('globalThis', context), context);
assert(vm.isContext(context));
assert.strictEqual(typeof context.Array, 'function'); // Can access builtins directly.
assert.deepStrictEqual(Object.keys(context), []); // Properties on the global proxy are not enumerable
}
{
// Check that vm.createContext can return the original context if re-passed.
const context = vm.createContext(vm.constants.DONT_CONTEXTIFY);
const context2 = new vm.createContext(context);
assert.strictEqual(context, context2);
}
{
// Check that the context is vanilla and that Script.runInContext works.
const context = vm.createContext(vm.constants.DONT_CONTEXTIFY);
const result =
new vm.Script('globalThis.hey = 1; Object.freeze(globalThis); globalThis.process')
.runInContext(context);
assert.strictEqual(globalThis.hey, undefined); // Should not leak into current context.
assert.strictEqual(result, undefined); // Vanilla context has no Node.js globals
}
{
// Check Script.runInNewContext works.
const result =
new vm.Script('globalThis.hey = 1; Object.freeze(globalThis); globalThis.process')
.runInNewContext(vm.constants.DONT_CONTEXTIFY);
assert.strictEqual(globalThis.hey, undefined); // Should not leak into current context.
assert.strictEqual(result, undefined); // Vanilla context has no Node.js globals
}
{
// Check that vm.runInNewContext() works
const result = vm.runInNewContext(
'globalThis.hey = 1; Object.freeze(globalThis); globalThis.process',
vm.constants.DONT_CONTEXTIFY);
assert.strictEqual(globalThis.hey, undefined); // Should not leak into current context.
assert.strictEqual(result, undefined); // Vanilla context has no Node.js globals
}
{
// Check that the global object of vanilla contexts work as expected.
const context = vm.createContext(vm.constants.DONT_CONTEXTIFY);
// Check mutation via globalThis.
vm.runInContext('globalThis.foo = 1;', context);
assert.strictEqual(globalThis.foo, undefined); // Should not pollute the current context.
assert.strictEqual(context.foo, 1);
assert.strictEqual(vm.runInContext('globalThis.foo', context), 1);
assert.strictEqual(vm.runInContext('foo', context), 1);
// Check mutation from outside.
context.foo = 2;
assert.strictEqual(context.foo, 2);
assert.strictEqual(vm.runInContext('globalThis.foo', context), 2);
assert.strictEqual(vm.runInContext('foo', context), 2);
// Check contextual mutation.
vm.runInContext('bar = 1;', context);
assert.strictEqual(globalThis.bar, undefined); // Should not pollute the current context.
assert.strictEqual(context.bar, 1);
assert.strictEqual(vm.runInContext('globalThis.bar', context), 1);
assert.strictEqual(vm.runInContext('bar', context), 1);
// Check adding new property from outside.
context.baz = 1;
assert.strictEqual(context.baz, 1);
assert.strictEqual(vm.runInContext('globalThis.baz', context), 1);
assert.strictEqual(vm.runInContext('baz', context), 1);
// Check mutation via Object.defineProperty().
vm.runInContext('Object.defineProperty(globalThis, "qux", {' +
'enumerable: false, configurable: false, get() { return 1; } })', context);
assert.strictEqual(globalThis.qux, undefined); // Should not pollute the current context.
assert.strictEqual(context.qux, 1);
assert.strictEqual(vm.runInContext('qux', context), 1);
const desc = Object.getOwnPropertyDescriptor(context, 'qux');
assert.strictEqual(desc.enumerable, false);
assert.strictEqual(desc.configurable, false);
assert.strictEqual(typeof desc.get, 'function');
assert.throws(() => { context.qux = 1; }, { name: 'TypeError' });
assert.throws(() => { Object.defineProperty(context, 'qux', { value: 1 }); }, { name: 'TypeError' });
// Setting a value without a setter fails silently.
assert.strictEqual(vm.runInContext('qux = 2; qux', context), 1);
assert.throws(() => {
vm.runInContext('Object.defineProperty(globalThis, "qux", { value: 1 });');
}, { name: 'TypeError' });
}
function checkFrozen(context) {
// Check mutation via globalThis.
vm.runInContext('globalThis.foo = 1', context); // Invoking setters on freezed object fails silently.
assert.strictEqual(context.foo, undefined);
assert.strictEqual(vm.runInContext('globalThis.foo', context), undefined);
assert.throws(() => {
vm.runInContext('foo', context); // It should not be looked up contextually.
}, {
name: 'ReferenceError'
});
// Check mutation from outside.
assert.throws(() => {
context.foo = 2;
}, { name: 'TypeError' });
assert.strictEqual(context.foo, undefined);
assert.strictEqual(vm.runInContext('globalThis.foo', context), undefined);
assert.throws(() => {
vm.runInContext('foo', context); // It should not be looked up contextually.
}, {
name: 'ReferenceError'
});
// Check contextual mutation.
vm.runInContext('bar = 1', context); // Invoking setters on freezed object fails silently.
assert.strictEqual(context.bar, undefined);
assert.strictEqual(vm.runInContext('globalThis.bar', context), undefined);
assert.throws(() => {
vm.runInContext('bar', context); // It should not be looked up contextually.
}, {
name: 'ReferenceError'
});
// Check mutation via Object.defineProperty().
assert.throws(() => {
vm.runInContext('Object.defineProperty(globalThis, "qux", {' +
'enumerable: false, configurable: false, get() { return 1; } })', context);
}, {
name: 'TypeError'
});
assert.strictEqual(context.qux, undefined);
assert.strictEqual(vm.runInContext('globalThis.qux', context), undefined);
assert.strictEqual(Object.getOwnPropertyDescriptor(context, 'qux'), undefined);
assert.throws(() => { Object.defineProperty(context, 'qux', { value: 1 }); }, { name: 'TypeError' });
assert.throws(() => {
vm.runInContext('qux', context);
}, {
name: 'ReferenceError'
});
}
{
// Check freezing the vanilla context's global object from within the context.
const context = vm.createContext(vm.constants.DONT_CONTEXTIFY);
// Only vanilla contexts' globals can be freezed. Contextified global objects cannot be freezed
// due to the presence of interceptors.
vm.runInContext('Object.freeze(globalThis)', context);
checkFrozen(context);
}
{
// Check freezing the vanilla context's global object from outside the context.
const context = vm.createContext(vm.constants.DONT_CONTEXTIFY);
Object.freeze(context);
checkFrozen(context);
}
// Check importModuleDynamically works.
(async function() {
{
const moduleUrl = fixtures.fileURL('es-modules', 'message.mjs');
const namespace = await import(moduleUrl.href);
// Check dynamic import works
const context = vm.createContext(vm.constants.DONT_CONTEXTIFY);
const script = new vm.Script(`import(${JSON.stringify(moduleUrl)})`, {
importModuleDynamically: vm.constants.USE_MAIN_CONTEXT_DEFAULT_LOADER,
});
const promise = script.runInContext(context);
assert.strictEqual(await promise, namespace);
}
})().catch(common.mustNotCall());