1// Copyright Joyent, Inc. and other Node contributors. 2// 3// Permission is hereby granted, free of charge, to any person obtaining a 4// copy of this software and associated documentation files (the 5// "Software"), to deal in the Software without restriction, including 6// without limitation the rights to use, copy, modify, merge, publish, 7// distribute, sublicense, and/or sell copies of the Software, and to permit 8// persons to whom the Software is furnished to do so, subject to the 9// following conditions: 10// 11// The above copyright notice and this permission notice shall be included 12// in all copies or substantial portions of the Software. 13// 14// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN 17// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 18// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 19// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 20// USE OR OTHER DEALINGS IN THE SOFTWARE. 21 22'use strict'; 23require('../common'); 24const assert = require('assert'); 25const { inspect } = require('util'); 26const vm = require('vm'); 27const Script = vm.Script; 28let script = new Script('"passed";'); 29 30// Run in a new empty context 31let context = vm.createContext(); 32let result = script.runInContext(context); 33assert.strictEqual(result, 'passed'); 34 35// Create a new pre-populated context 36context = vm.createContext({ 'foo': 'bar', 'thing': 'lala' }); 37assert.strictEqual(context.foo, 'bar'); 38assert.strictEqual(context.thing, 'lala'); 39 40// Test updating context 41script = new Script('foo = 3;'); 42result = script.runInContext(context); 43assert.strictEqual(context.foo, 3); 44assert.strictEqual(context.thing, 'lala'); 45 46// Issue GH-227: 47assert.throws(() => { 48 vm.runInNewContext('', null, 'some.js'); 49}, { 50 code: 'ERR_INVALID_ARG_TYPE', 51 name: 'TypeError' 52}); 53 54// Issue GH-1140: 55// Test runInContext signature 56let gh1140Exception; 57try { 58 vm.runInContext('throw new Error()', context, 'expected-filename.js'); 59} catch (e) { 60 gh1140Exception = e; 61 assert.ok(/expected-filename/.test(e.stack), 62 `expected appearance of filename in Error stack: ${inspect(e)}`); 63} 64// This is outside of catch block to confirm catch block ran. 65assert.strictEqual(gh1140Exception.toString(), 'Error'); 66 67const nonContextualObjectError = { 68 code: 'ERR_INVALID_ARG_TYPE', 69 name: 'TypeError', 70 message: /must be of type object/ 71}; 72const contextifiedObjectError = { 73 code: 'ERR_INVALID_ARG_TYPE', 74 name: 'TypeError', 75 message: /The "contextifiedObject" argument must be an vm\.Context/ 76}; 77 78[ 79 [undefined, nonContextualObjectError], 80 [null, nonContextualObjectError], 81 [0, nonContextualObjectError], 82 [0.0, nonContextualObjectError], 83 ['', nonContextualObjectError], 84 [{}, contextifiedObjectError], 85 [[], contextifiedObjectError], 86].forEach((e) => { 87 assert.throws(() => { script.runInContext(e[0]); }, e[1]); 88 assert.throws(() => { vm.runInContext('', e[0]); }, e[1]); 89}); 90 91// Issue GH-693: 92// Test RegExp as argument to assert.throws 93script = vm.createScript('const assert = require(\'assert\'); assert.throws(' + 94 'function() { throw "hello world"; }, /hello/);', 95 'some.js'); 96script.runInNewContext({ require }); 97 98// Issue GH-7529 99script = vm.createScript('delete b'); 100let ctx = {}; 101Object.defineProperty(ctx, 'b', { configurable: false }); 102ctx = vm.createContext(ctx); 103assert.strictEqual(script.runInContext(ctx), false); 104 105// Error on the first line of a module should have the correct line and column 106// number. 107{ 108 let stack = null; 109 assert.throws(() => { 110 vm.runInContext(' throw new Error()', context, { 111 filename: 'expected-filename.js', 112 lineOffset: 32, 113 columnOffset: 123 114 }); 115 }, (err) => { 116 stack = err.stack; 117 return /^ \^/m.test(stack) && 118 /expected-filename\.js:33:131/.test(stack); 119 }, `stack not formatted as expected: ${stack}`); 120} 121 122// https://github.com/nodejs/node/issues/6158 123ctx = new Proxy({}, {}); 124assert.strictEqual(typeof vm.runInNewContext('String', ctx), 'function'); 125