Comparing version 0.9.0 to 0.13.7
@@ -6,2 +6,13 @@ # Change Log | ||
<a name="0.13.7"></a> | ||
## [0.13.7](https://github.com/Igmat/baset/compare/v0.13.6...v0.13.7) (2018-08-30) | ||
### Bug Fixes | ||
* **vm:** correct global for vm without broken function constructor ([1405c53](https://github.com/Igmat/baset/commit/1405c53)), closes [#58](https://github.com/Igmat/baset/issues/58) | ||
<a name="0.9.0"></a> | ||
@@ -8,0 +19,0 @@ # [0.9.0](https://github.com/Igmat/baset/compare/v0.8.0...v0.9.0) (2018-03-03) |
@@ -1,450 +0,305 @@ | ||
const {Script} = host.require('vm'); | ||
const fs = host.require('fs'); | ||
const pa = host.require('path'); | ||
const console = host.console; | ||
const BUILTIN_MODULES = host.process.binding('natives'); | ||
const JSON_PARSE = JSON.parse; | ||
/** | ||
* @param {Object} host Hosts's internal objects. | ||
*/ | ||
return ((vm, host) => { | ||
'use strict'; | ||
const global = this; | ||
const TIMERS = new host.WeakMap() | ||
const BUILTINS = {}; | ||
const CACHE = {}; | ||
const EXTENSIONS = { | ||
[".json"](module, filename) { | ||
try { | ||
var code = fs.readFileSync(filename, "utf8"); | ||
} catch (e) { | ||
throw Contextify.value(e); | ||
} | ||
module.exports = JSON_PARSE(code); | ||
}, | ||
[".node"](module, filename) { | ||
// we need to skip this check in order to work with `canvas-prebuilt` package | ||
// FIXME: find better workaround | ||
// if (vm.options.require.context === 'sandbox') throw new VMError('Native modules can be required only with context set to \'host\'.'); | ||
try { | ||
module.exports = Contextify.readonly(host.require(filename)); | ||
} catch (e) { | ||
throw Contextify.value(e); | ||
} | ||
} | ||
}; | ||
for (var i = 0; i < vm.options.sourceExtensions.length; i++) { | ||
var ext = vm.options.sourceExtensions[i]; | ||
EXTENSIONS[ext] = (module, filename, dirname) => { | ||
if (vm.options.require.context !== 'sandbox') { | ||
try { | ||
module.exports = Contextify.readonly(host.require(filename)); | ||
} catch (e) { | ||
throw Contextify.value(e); | ||
} | ||
} else { | ||
try { | ||
// Load module | ||
var contents = fs.readFileSync(filename, "utf8") | ||
if (typeof vm.options.compiler === "function") { | ||
contents = vm.options.compiler(contents, filename) | ||
} | ||
var code = `(function (exports, require, module, __filename, __dirname) { 'use strict'; ${contents} \n});`; | ||
// Precompile script | ||
const script = new Script(code, { | ||
filename: filename || "vm.js", | ||
displayErrors: false | ||
}); | ||
var closure = script.runInContext(global, { | ||
filename: filename || "vm.js", | ||
displayErrors: false | ||
}); | ||
} catch (ex) { | ||
throw Contextify.value(ex); | ||
} | ||
// run script | ||
closure(module.exports, module.require, module, filename, dirname); | ||
} | ||
} | ||
} | ||
/** | ||
* Resolve filename. | ||
*/ | ||
const originalResolveFilename = function(path) { | ||
path = pa.resolve(path); | ||
const exists = fs.existsSync(path); | ||
const isdir = exists ? fs.statSync(path).isDirectory() : false; | ||
// direct file match | ||
if (exists && !isdir) return path; | ||
// load as file | ||
for (var i = 0; i < vm.options.sourceExtensions.length; i++) { | ||
var ext = vm.options.sourceExtensions[i]; | ||
if (fs.existsSync(`${path}${ext}`)) { | ||
const stat = fs.statSync(`${path}${ext}`); | ||
"use strict"; | ||
// tslint:disable-next-line:no-unused-expression | ||
(function sandbox(vm, host) { | ||
'use strict'; | ||
const { Script } = host.require('vm'); | ||
const fs = host.require('fs'); | ||
const pa = host.require('path'); | ||
// tslint:disable-next-line:no-this-assignment | ||
const global = this; | ||
// tslint:disable-next-line:forin | ||
for (const name in host) { | ||
global[name] = host[name]; | ||
} | ||
delete global.require; | ||
Object.setPrototypeOf(global, Object.prototype); | ||
Object.defineProperties(global, { | ||
global: { value: global }, | ||
GLOBAL: { value: global }, | ||
root: { value: global }, | ||
isVM: { value: true }, | ||
}); | ||
const ERROR_CST = Error.captureStackTrace; | ||
/** | ||
* VMError definition. | ||
*/ | ||
class VMError extends Error { | ||
constructor(message, code) { | ||
super(message); | ||
this.code = code; | ||
ERROR_CST(this, this.constructor); | ||
} | ||
} | ||
global.VMError = VMError; | ||
// TODO: check if really exists in runtime | ||
// tslint:disable-next-line:no-any | ||
const BUILTIN_MODULES = host.process.binding('natives'); | ||
const JSON_PARSE = JSON.parse; | ||
const BUILTINS = {}; | ||
const CACHE = {}; | ||
const EXTENSIONS = { | ||
['.json'](module, filename) { | ||
module.exports = JSON_PARSE(fs.readFileSync(filename, 'utf8')); | ||
}, | ||
['.node'](module, filename) { | ||
module.exports = host.require(filename); | ||
}, | ||
}; | ||
for (const ext of vm.options.sourceExtensions) { | ||
EXTENSIONS[ext] = (module, filename, dirname) => { | ||
if (typeof vm.options.require === 'boolean' || vm.options.require.context !== 'sandbox') { | ||
module.exports = host.require(filename); | ||
} | ||
else { | ||
// Load module | ||
let contents = fs.readFileSync(filename, 'utf8'); | ||
if (filename.endsWith(`tcomb${pa.sep}lib${pa.sep}isArray.js`)) { | ||
contents = `module.exports = function isArray(x) { | ||
return Array.isArray ? Array.isArray(x) : x instanceof Array; | ||
};`; | ||
} | ||
if (typeof vm.options.compiler === 'function') { | ||
contents = vm.options.compiler(contents, filename); | ||
} | ||
const code = `(function (exports, require, module, __filename, __dirname) { 'use strict'; ${contents} \n});`; | ||
// Precompile script | ||
const script = new Script(code, { | ||
filename: filename || 'vm.js', | ||
displayErrors: false, | ||
}); | ||
const closure = script.runInContext(global, { | ||
filename: filename || 'vm.js', | ||
displayErrors: false, | ||
}); | ||
// run script | ||
closure(module.exports, module.require, module, filename, dirname); | ||
} | ||
}; | ||
} | ||
/** | ||
* Resolve filename. | ||
*/ | ||
function originalResolveFilename(path) { | ||
const resolvedPath = pa.resolve(path); | ||
const exists = fs.existsSync(resolvedPath); | ||
const isDir = exists ? fs.statSync(resolvedPath).isDirectory() : false; | ||
// direct file match | ||
if (exists && !isDir) | ||
return resolvedPath; | ||
// load as file | ||
for (const ext of vm.options.sourceExtensions) { | ||
if (fs.existsSync(`${resolvedPath}${ext}`)) { | ||
const stat = fs.statSync(`${resolvedPath}${ext}`); | ||
// some directories could be named like `asn1.js`, so we have to check it here | ||
if (stat && !stat.isDirectory()) { | ||
return `${path}${ext}` | ||
} | ||
}; | ||
} | ||
if (fs.existsSync(`${path}.node`)) return `${path}.node`; | ||
if (fs.existsSync(`${path}.json`)) return `${path}.json`; | ||
// load as directory | ||
if (fs.existsSync(`${path}/package.json`)) { | ||
try { | ||
var pkg = JSON.parse(fs.readFileSync(`${path}/package.json`, "utf8")); | ||
if (pkg.main == null) pkg.main = "index.js"; | ||
} catch (ex) { | ||
throw new VMError(`Module '${modulename}' has invalid package.json`, "EMODULEINVALID"); | ||
} | ||
return _resolveFilename(`${path}/${pkg.main}`); | ||
} | ||
for (var i = 0; i < vm.options.sourceExtensions.length; i++) { | ||
var ext = vm.options.sourceExtensions[i]; | ||
if (fs.existsSync(`${path}/index${ext}`)) return `${path}/index${ext}`; | ||
} | ||
if (fs.existsSync(`${path}/index.node`)) return `${path}/index.node`; | ||
return null; | ||
}; | ||
const _resolveFilename = vm.options.resolveFilename | ||
? function (path) { | ||
return vm.options.resolveFilename(originalResolveFilename, path); | ||
if (stat && !stat.isDirectory()) { | ||
return `${resolvedPath}${ext}`; | ||
} | ||
} | ||
} | ||
if (fs.existsSync(`${resolvedPath}.node`)) | ||
return `${resolvedPath}.node`; | ||
if (fs.existsSync(`${resolvedPath}.json`)) | ||
return `${resolvedPath}.json`; | ||
// load as directory | ||
if (fs.existsSync(`${resolvedPath}/package.json`)) { | ||
try { | ||
const pkg = JSON.parse(fs.readFileSync(`${resolvedPath}/package.json`, 'utf8')); | ||
if (pkg.main === undefined) | ||
pkg.main = 'index.js'; | ||
return resolveFilename(`${resolvedPath}/${pkg.main}`); | ||
} | ||
catch (ex) { | ||
throw new VMError(`Module '${resolvedPath}' has invalid package.json`, 'EMODULEINVALID'); | ||
} | ||
} | ||
for (const ext of vm.options.sourceExtensions) { | ||
if (fs.existsSync(`${resolvedPath}/index${ext}`)) | ||
return `${resolvedPath}/index${ext}`; | ||
} | ||
if (fs.existsSync(`${resolvedPath}/index.node`)) | ||
return `${resolvedPath}/index.node`; | ||
return null; | ||
} | ||
const { resolveFilename: providedResolveFilename } = vm.options; | ||
const resolveFilename = providedResolveFilename | ||
? (path) => providedResolveFilename(originalResolveFilename, path) | ||
: originalResolveFilename; | ||
/** | ||
* Builtin require. | ||
*/ | ||
const _requireBuiltin = function(modulename) { | ||
if (modulename === 'buffer') return ({Buffer}); | ||
if (BUILTINS[modulename]) return BUILTINS[modulename].exports; // Only compiled builtins are stored here | ||
if (modulename === 'util') { | ||
return Contextify.readonly(host.require(modulename), { | ||
// Allows VM context to use util.inherits | ||
inherits: function(ctor, superCtor) { | ||
ctor.super_ = superCtor; | ||
Object.setPrototypeOf(ctor.prototype, superCtor.prototype); | ||
} | ||
}); | ||
} | ||
if (modulename === 'events') { | ||
try { | ||
const script = new Script(`(function (exports, require, module, process) { 'use strict'; ${BUILTIN_MODULES[modulename]} \n});`, { | ||
filename: `${modulename}.vm.js` | ||
}); | ||
// setup module scope | ||
const module = BUILTINS[modulename] = { | ||
exports: {}, | ||
require: _requireBuiltin | ||
}; | ||
// run script | ||
script.runInContext(global)(module.exports, module.require, module, host.process); | ||
return module.exports; | ||
} catch (e) { | ||
throw Contextify.value(e); | ||
} | ||
} | ||
return Contextify.readonly(host.require(modulename)); | ||
}; | ||
/** | ||
* Prepare require. | ||
*/ | ||
const _prepareRequire = function(current_dirname) { | ||
const _require = function (modulename) { | ||
if (vm.options.nesting && modulename === 'vm2') return {VM: Contextify.readonly(host.VM), NodeVM: Contextify.readonly(host.NodeVM)}; | ||
if (!vm.options.require) throw new VMError(`Access denied to require '${modulename}'`, "EDENIED"); | ||
if (modulename == null) throw new VMError("Module '' not found.", "ENOTFOUND"); | ||
if (typeof modulename !== 'string') throw new VMError(`Invalid module name '${modulename}'`, "EINVALIDNAME"); | ||
// Mock? | ||
if (vm.options.require.mock && vm.options.require.mock[modulename]) { | ||
return Contextify.readonly(vm.options.require.mock[modulename]); | ||
} | ||
// Builtin? | ||
if (BUILTIN_MODULES[modulename]) { | ||
if (host.Array.isArray(vm.options.require.builtin)) { | ||
if (vm.options.require.builtin.indexOf('*') >= 0) { | ||
if (vm.options.require.builtin.indexOf(`-${modulename}`) >= 0) { | ||
throw new VMError(`Access denied to require '${modulename}'`, "EDENIED"); | ||
} | ||
} else if (vm.options.require.builtin.indexOf(modulename) === -1) { | ||
throw new VMError(`Access denied to require '${modulename}'`, "EDENIED"); | ||
} | ||
} else if (vm.options.require.builtin) { | ||
if (!vm.options.require.builtin[modulename]) { | ||
throw new VMError(`Access denied to require '${modulename}'`, "EDENIED"); | ||
} | ||
} else { | ||
throw new VMError(`Access denied to require '${modulename}'`, "EDENIED"); | ||
} | ||
return _requireBuiltin(modulename); | ||
} | ||
// External? | ||
if (!vm.options.require.external) throw new VMError(`Access denied to require '${modulename}'`, "EDENIED"); | ||
if (/^(\.|\.\/|\.\.\/)/.exec(modulename)) { | ||
function resolveFilenameLikeNode(modulename, currentDirname) { | ||
// it could be found by custom resolver | ||
let filename = resolveFilename(modulename); | ||
if (!filename) { | ||
// Check node_modules in path | ||
if (!currentDirname) | ||
throw new VMError('You must specify script path to load relative modules.', 'ENOPATH'); | ||
if (typeof vm.options.require !== 'boolean' && Array.isArray(vm.options.require.external)) { | ||
const isWhitelisted = vm.options.require.external.indexOf(modulename) !== -1; | ||
if (!isWhitelisted) | ||
throw new VMError(`The module '${modulename}' is not whitelisted in VM.`, 'EDENIED'); | ||
} | ||
const paths = currentDirname.split(pa.sep); | ||
while (paths.length) { | ||
const path = paths.join(pa.sep); | ||
// console.log(`${path}${pa.sep}node_modules${pa.sep}${modulename}`) | ||
filename = resolveFilename(`${path}${pa.sep}node_modules${pa.sep}${modulename}`); | ||
if (filename) | ||
break; | ||
paths.pop(); | ||
} | ||
} | ||
return filename; | ||
} | ||
function createModule(id, require, filename = id, exports = {}) { | ||
return { | ||
id, | ||
filename, | ||
exports, | ||
require, | ||
loaded: true, | ||
parent: null, | ||
children: [], | ||
paths: [id, filename], | ||
}; | ||
} | ||
/** | ||
* Builtin require. | ||
*/ | ||
function getBuiltIn(modulename) { | ||
function requireBuiltin(builtInName) { | ||
if (BUILTINS[builtInName]) | ||
return BUILTINS[builtInName].exports; // Only compiled builtins are stored here | ||
if (builtInName === 'events') { | ||
try { | ||
const script = new Script(`(function (exports, require, module, process) { 'use strict'; ${BUILTIN_MODULES[builtInName]} \n});`, { | ||
filename: `${builtInName}.vm.js`, | ||
}); | ||
// setup module scope | ||
const module = createModule(builtInName, requireBuiltin, `${builtInName}.vm.js`); | ||
BUILTINS[builtInName] = module; | ||
// run script | ||
script.runInContext(global)(module.exports, module.require, module, host.process); | ||
return module.exports; | ||
} | ||
catch (e) { | ||
throw e; | ||
} | ||
} | ||
return host.require(builtInName); | ||
} | ||
if (typeof vm.options.require !== 'boolean' && host.Array.isArray(vm.options.require.builtin)) { | ||
if (vm.options.require.builtin.indexOf('*') >= 0) { | ||
if (vm.options.require.builtin.indexOf(`-${modulename}`) >= 0) { | ||
throw new VMError(`Access denied to require '${modulename}'`, 'EDENIED'); | ||
} | ||
} | ||
else if (vm.options.require.builtin.indexOf(modulename) === -1) { | ||
throw new VMError(`Access denied to require '${modulename}'`, 'EDENIED'); | ||
} | ||
} | ||
else if (typeof vm.options.require !== 'boolean' && | ||
vm.options.require.builtin && | ||
!host.Array.isArray(vm.options.require.builtin)) { | ||
if (!vm.options.require.builtin[modulename]) { | ||
throw new VMError(`Access denied to require '${modulename}'`, 'EDENIED'); | ||
} | ||
} | ||
else { | ||
throw new VMError(`Access denied to require '${modulename}'`, 'EDENIED'); | ||
} | ||
return requireBuiltin(modulename); | ||
} | ||
/** | ||
* Prepare require. | ||
*/ | ||
function prepareRequire(currentDirname) { | ||
return function require(modulename) { | ||
if (vm.options.nesting && modulename === 'baset-vm') | ||
return { NodeVM: host.NodeVM }; | ||
if (!vm.options.require) | ||
throw new VMError(`Access denied to require '${modulename}'`, 'EDENIED'); | ||
if (modulename === undefined) | ||
throw new VMError("Module '' not found.", 'ENOTFOUND'); | ||
if (typeof modulename !== 'string') | ||
throw new VMError(`Invalid module name '${modulename}'`, 'EINVALIDNAME'); | ||
// Mock? | ||
if (typeof vm.options.require !== 'boolean' && vm.options.require.mock && vm.options.require.mock[modulename]) { | ||
return vm.options.require.mock[modulename]; | ||
} | ||
// Builtin? | ||
if (BUILTIN_MODULES[modulename]) | ||
return getBuiltIn(modulename); | ||
// External? | ||
if (typeof vm.options.require === 'boolean' || !vm.options.require.external) { | ||
throw new VMError(`Access denied to require '${modulename}'`, 'EDENIED'); | ||
} | ||
let filename = null; | ||
if (/^(\.|\.\/|\.\.\/)/.exec(modulename)) { | ||
// Module is relative file, e.g. ./script.js or ../script.js | ||
if (!current_dirname) throw new VMError("You must specify script path to load relative modules.", "ENOPATH"); | ||
var filename = _resolveFilename(`${current_dirname}/${modulename}`); | ||
} else if (/^(\/|\\|[a-zA-Z]:\\)/.exec(modulename)) { | ||
// Module is absolute file, e.g. /script.js or //server/script.js or C:\script.js | ||
var filename = _resolveFilename(modulename); | ||
} else { | ||
// it could be found by custom resolver | ||
var filename = _resolveFilename(modulename); | ||
if (!filename) { | ||
// Check node_modules in path | ||
if (!current_dirname) throw new VMError("You must specify script path to load relative modules.", "ENOPATH"); | ||
if(Array.isArray(vm.options.require.external)) { | ||
const isWhitelisted = vm.options.require.external.indexOf(modulename) !== -1 | ||
if (!isWhitelisted) throw new VMError(`The module '${modulename}' is not whitelisted in VM.`, "EDENIED"); | ||
} | ||
const paths = current_dirname.split(pa.sep); | ||
while (paths.length) { | ||
let path = paths.join(pa.sep); | ||
// console.log(`${path}${pa.sep}node_modules${pa.sep}${modulename}`) | ||
filename = _resolveFilename(`${path}${pa.sep}node_modules${pa.sep}${modulename}`); | ||
if (filename) break; | ||
paths.pop(); | ||
} | ||
if (!currentDirname) | ||
throw new VMError('You must specify script path to load relative modules.', 'ENOPATH'); | ||
filename = resolveFilename(`${currentDirname}/${modulename}`); | ||
} | ||
else { | ||
// Module is absolute file, e.g. /script.js or //server/script.js or C:\script.js | ||
filename = (/^(\/|\\|[a-zA-Z]:\\)/.exec(modulename)) | ||
? resolveFilename(modulename) | ||
: resolveFilenameLikeNode(modulename, currentDirname); | ||
} | ||
if (!filename) | ||
throw new VMError(`Cannot find module '${modulename}'`, 'ENOTFOUND'); | ||
// return cache whenever possible | ||
if (CACHE[filename]) | ||
return CACHE[filename].exports; | ||
const dirname = pa.dirname(filename); | ||
const extname = pa.extname(filename); | ||
if (vm.options.require.root) { | ||
const requiredPath = pa.resolve(vm.options.require.root); | ||
if (dirname.indexOf(requiredPath) !== 0) { | ||
throw new VMError(`Module '${modulename}' is not allowed to be required. The path is outside the border!`, 'EDENIED'); | ||
} | ||
} | ||
if (!filename) throw new VMError(`Cannot find module '${modulename}'`, "ENOTFOUND"); | ||
// return cache whenever possible | ||
if (CACHE[filename]) return CACHE[filename].exports; | ||
const dirname = pa.dirname(filename); | ||
const extname = pa.extname(filename); | ||
if (vm.options.require.root) { | ||
const requiredPath = pa.resolve(vm.options.require.root); | ||
if (dirname.indexOf(requiredPath) !== 0) { | ||
throw new VMError(`Module '${modulename}' is not allowed to be required. The path is outside the border!`, "EDENIED"); | ||
} | ||
} | ||
const module = CACHE[filename] = { | ||
filename, | ||
exports: {}, | ||
require: _prepareRequire(dirname) | ||
}; | ||
// lookup extensions | ||
if (EXTENSIONS[extname]) { | ||
EXTENSIONS[extname](module, filename, dirname); | ||
return module.exports; | ||
} | ||
throw new VMError(`Failed to load '${modulename}': Unknown type.`, "ELOADFAIL"); | ||
}; | ||
return _require; | ||
}; | ||
/** | ||
* Prepare sandbox. | ||
*/ | ||
global.setTimeout = function(callback, delay, ...args) { | ||
const tmr = host.setTimeout(function() { | ||
callback.apply(null, args) | ||
}, delay); | ||
const local = { | ||
ref() { return tmr.ref(); }, | ||
unref() { return tmr.unref(); } | ||
}; | ||
TIMERS.set(local, tmr); | ||
return local; | ||
}; | ||
global.setInterval = function(callback, interval, ...args) { | ||
const tmr = host.setInterval(function() { | ||
callback.apply(null, args) | ||
}, interval); | ||
const local = { | ||
ref() { return tmr.ref(); }, | ||
unref() { return tmr.unref(); } | ||
}; | ||
TIMERS.set(local, tmr); | ||
return local; | ||
}; | ||
global.setImmediate = function(callback, ...args) { | ||
const tmr = host.setImmediate(function() { | ||
callback.apply(null, args) | ||
}); | ||
const local = { | ||
ref() { return tmr.ref(); }, | ||
unref() { return tmr.unref(); } | ||
}; | ||
TIMERS.set(local, tmr); | ||
return local; | ||
}; | ||
global.clearTimeout = function(local) { | ||
host.clearTimeout(TIMERS.get(local)); | ||
return null; | ||
}; | ||
global.clearInterval = function(local) { | ||
host.clearInterval(TIMERS.get(local)); | ||
return null; | ||
}; | ||
global.clearImmediate = function(local) { | ||
host.clearImmediate(TIMERS.get(local)); | ||
return null; | ||
}; | ||
} | ||
const module = createModule(filename, prepareRequire(dirname)); | ||
CACHE[filename] = module; | ||
// lookup extensions | ||
if (EXTENSIONS[extname]) { | ||
EXTENSIONS[extname](module, filename, dirname); | ||
return module.exports; | ||
} | ||
throw new VMError(`Failed to load '${modulename}': Unknown type.`, 'ELOADFAIL'); | ||
}; | ||
} | ||
/** | ||
* Prepare sandbox. | ||
*/ | ||
let processCwd; | ||
global.process = { | ||
argv: [], | ||
title: host.process.title, | ||
version: host.process.version, | ||
versions: Contextify.readonly(host.process.versions), | ||
arch: host.process.arch, | ||
platform: host.process.platform, | ||
env: {}, | ||
pid: host.process.pid, | ||
features: Contextify.readonly(host.process.features), | ||
uptime: host.process.uptime, | ||
nextTick(callback) { return host.process.nextTick(() => callback.call(null)); }, | ||
hrtime() { return host.process.hrtime(); }, | ||
cwd() {return processCwd || host.process.cwd(); }, | ||
on(name, handler) { | ||
if (name !== 'beforeExit' && name !== 'exit') { | ||
throw new Error(`Access denied to listen for '${name}' event.`); | ||
} | ||
host.process.on(name, Decontextify.value(handler)); | ||
return this; | ||
}, | ||
global.process = Object.assign({}, host.process, { argv: [], env: {}, cwd() { return processCwd || host.process.cwd(); }, | ||
chdir(directory) { | ||
processCwd = directory; | ||
}, | ||
once(name, handler) { | ||
if (name !== 'beforeExit' && name !== 'exit') { | ||
throw new Error(`Access denied to listen for '${name}' event.`); | ||
} | ||
host.process.once(name, Decontextify.value(handler)); | ||
return this; | ||
}, | ||
listeners(name) { | ||
return Contextify.readonly(host.process.listeners(name)); | ||
}, | ||
removeListener(name, handler) { | ||
host.process.removeListener(name, Decontextify.value(handler)); | ||
return this; | ||
}, | ||
umask() { | ||
if (arguments.length) { | ||
throw new Error("Access denied to set umask."); | ||
} | ||
return host.process.umask(); | ||
}, | ||
}; | ||
if (vm.options.console === 'inherit') { | ||
global.console = Contextify.readonly(host.console); | ||
} else if (vm.options.console === 'redirect') { | ||
global.console = { | ||
log(...args) { | ||
vm.emit('console.log', ...Decontextify.arguments(args)); | ||
return null; | ||
}, | ||
info(...args) { | ||
vm.emit('console.info', ...Decontextify.arguments(args)); | ||
return null; | ||
}, | ||
warn(...args) { | ||
vm.emit('console.warn', ...Decontextify.arguments(args)); | ||
return null; | ||
}, | ||
error(...args) { | ||
vm.emit('console.error', ...Decontextify.arguments(args)); | ||
return null; | ||
}, | ||
dir(...args) { | ||
vm.emit('console.dir', ...Decontextify.arguments(args)); | ||
return null; | ||
}, | ||
time: () => {}, | ||
timeEnd: () => {}, | ||
trace(...args) { | ||
vm.emit('console.trace', ...Decontextify.arguments(args)); | ||
return null; | ||
} | ||
}; | ||
} | ||
/* | ||
Return contextized require. | ||
*/ | ||
return _prepareRequire; | ||
})(vm, host); | ||
} }); | ||
if (vm.options.console === 'inherit') { | ||
global.console = host.console; | ||
} | ||
else if (vm.options.console === 'redirect') { | ||
global.console = Object.assign({}, host.console, { log(...args) { | ||
vm.emit('console.log', ...args); | ||
}, | ||
info(...args) { | ||
vm.emit('console.info', ...args); | ||
}, | ||
warn(...args) { | ||
vm.emit('console.warn', ...args); | ||
}, | ||
error(...args) { | ||
vm.emit('console.error', ...args); | ||
}, | ||
dir(...args) { | ||
vm.emit('console.dir', ...args); | ||
}, time: () => { }, timeEnd: () => { }, trace(...args) { | ||
vm.emit('console.trace', ...args); | ||
} }); | ||
} | ||
/* | ||
Return contextized require. | ||
*/ | ||
return prepareRequire; | ||
}); | ||
//# sourceMappingURL=sandbox.js.map |
{ | ||
"name": "baset-vm", | ||
"version": "0.9.0", | ||
"version": "0.13.7", | ||
"description": "VM package for BaseT project.", | ||
@@ -21,8 +21,23 @@ "keywords": [ | ||
}, | ||
"main": "index.js", | ||
"main": "dist/index.js", | ||
"types": "dist/index.d.ts", | ||
"engines": { | ||
"node": ">=6.0" | ||
}, | ||
"scripts": {}, | ||
"types": "index.d.ts" | ||
"scripts": { | ||
"build": "npm run tslint && tsc", | ||
"watch": "npm run tslint && tsc -w", | ||
"tslint": "tslint -c tslint.json -p tsconfig.json", | ||
"test": "baset", | ||
"accept": "baset accept", | ||
"doctoc": "doctoc README.md", | ||
"prepublish": "npm run doctoc" | ||
}, | ||
"devDependencies": { | ||
"@types/node": "^10.3.1", | ||
"baset": "^0.13.7", | ||
"doctoc": "^1.3.0", | ||
"tslint": "^5.9.1", | ||
"typescript": "3.0.1" | ||
} | ||
} |
@@ -0,1 +1,26 @@ | ||
<!-- START doctoc generated TOC please keep comment here to allow auto update --> | ||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE --> | ||
**Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)* | ||
- [BaseT VM](#baset-vm) | ||
- [vm2 [![NPM Version][npm-image]][npm-url] [![NPM Downloads][downloads-image]][downloads-url] [![Package Quality][quality-image]][quality-url] [![Travis CI][travis-image]][travis-url]](#vm2-npm-versionnpm-imagenpm-url-npm-downloadsdownloads-imagedownloads-url-package-qualityquality-imagequality-url-travis-citravis-imagetravis-url) | ||
- [Installation](#installation) | ||
- [Quick Example](#quick-example) | ||
- [Documentation](#documentation) | ||
- [VM](#vm) | ||
- [NodeVM](#nodevm) | ||
- [Loading modules by relative path](#loading-modules-by-relative-path) | ||
- [VMScript](#vmscript) | ||
- [Error handling](#error-handling) | ||
- [Read-only objects (experimental)](#read-only-objects-experimental) | ||
- [Cross-sandbox relationships](#cross-sandbox-relationships) | ||
- [CLI](#cli) | ||
- [Known Issues](#known-issues) | ||
- [Sponsors](#sponsors) | ||
- [License](#license) | ||
<!-- END doctoc generated TOC please keep comment here to allow auto update --> | ||
[![Known Vulnerabilities](https://snyk.io/test/npm/baset-vm/badge.svg)](https://snyk.io/test/npm/baset-vm) | ||
# BaseT VM | ||
@@ -2,0 +27,0 @@ > VM for [BaseT](https://github.com/Igmat/baset) project. |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Debug access
Supply chain riskUses debug, reflection and dynamic code execution features.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Debug access
Supply chain riskUses debug, reflection and dynamic code execution features.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
15
380
59471
5
669
5
1