class NodeVM extends EventEmitter {
/**
* Create NodeVM instance.
*
* Unlike VM, NodeVM lets you use require same way like in regular node.
*
* @param {Object} [options] VM options.
* @return {NodeVM}
*/
constructor(options = {}) {
super();
// defaults
this.options = {
sandbox: options.sandbox != null ? options.sandbox : null,
console: options.console != null ? options.console : 'inherit',
require: options.require != null ? options.require : false,
compiler: options.compiler != null ? options.compiler : 'javascript',
require: options.require != null ? options.require : false,
nesting: options.nesting != null ? options.nesting : false,
wrapper: options.wrapper != null ? options.wrapper : 'commonjs'
};
const host = {
require,
process,
console,
setTimeout,
setInterval,
setImmediate,
clearTimeout,
clearInterval,
clearImmediate,
String,
Number,
Buffer,
Boolean,
Array,
Date,
Error,
RangeError,
ReferenceError,
SyntaxError,
TypeError,
RegExp,
Function,
Object,
VMError,
Proxy,
Reflect,
Map,
WeakMap,
Set,
WeakSet,
Promise
}
if (this.options.nesting) {
host.VM = VM;
host.NodeVM = NodeVM;
}
this._context = vm.createContext();
Object.defineProperty(this, '_internal', {
value: vm.runInContext(`(function(require, host) { ${cf} \n})`, this._context, {
filename: `${__dirname}/contextify.js`,
displayErrors: false
}).call(this._context, require, host)
})
const closure = vm.runInContext(`(function (vm, host, Contextify, Decontextify, Buffer) { ${sb} \n})`, this._context, {
filename: `${__dirname}/sandbox.js`,
displayErrors: false
})
Object.defineProperty(this, '_prepareRequire', {
value: closure.call(this._context, this, host, this._internal.Contextify, this._internal.Decontextify, this._internal.Buffer)
})
// prepare global sandbox
if (this.options.sandbox) {
if ('object' !== typeof this.options.sandbox) {
throw new VMError("Sandbox must be object.");
}
for (let name in this.options.sandbox) {
this._internal.Contextify.globalValue(this.options.sandbox[name], name);
}
}
if (this.options.require && this.options.require.import) {
if (!Array.isArray(this.options.require.import)) {
this.options.require.import = [this.options.require.import];
}
for (let i = 0, l = this.options.require.import.length; i < l; i++) {
this.require(this.options.require.import[i]);
}
}
}
/**
* @deprecated
*/
call(method, ...args) {
if ('function' === typeof method) {
return method.apply(args);
} else {
throw new VMError("Unrecognized method type.");
}
}
/**
* Freezes the object inside VM making it read-only. Not available for primitive values.
*
* @static
* @param {*} object Object to freeze.
* @param {String} [globalName] Whether to add the object to global.
* @return {*} Object to freeze.
*/
freeze(value, globalName) {
this._internal.Contextify.readonly(value);
if (global) this._internal.Contextify.globalValue(value, globalName);
return value;
}
/**
* Protects the object inside VM making impossible to set functions as it's properties. Not available for primitive values.
*
* @static
* @param {*} object Object to protect.
* @param {String} [globalName] Whether to add the object to global.
* @return {*} Object to protect.
*/
protect(value, globalName) {
this._internal.Contextify.protected(value);
if (global) this._internal.Contextify.globalValue(value, globalName);
return value;
}
/**
* Require a module in VM and return it's exports.
*
* @param {String} module Module name.
* @return {*} Exported module.
*/
require(module) {
return this.run(`module.exports = require('${module}');`, 'vm.js');
}
/**
* Run the code in NodeVM.
*
* First time you run this method, code is executed same way like in node's regular `require` - it's executed with `module`, `require
`, `exports`, `__dirname`, `__filename` variables and expect result in `mo ...
n/a
class VM extends EventEmitter {
/**
* Makes the object read only.
*
* @static
* @param {*} object Object to freeze.
* @return {*} Frozen object.
*/
/**
* Create VM instance.
*
* @param {Object} [options] VM options.
* @return {VM}
*/
constructor(options = {}) {
super();
// defaults
this.options = {
timeout: options.timeout != null ? options.timeout : undefined,
sandbox: options.sandbox != null ? options.sandbox : null,
compiler: options.compiler != null ? options.compiler : 'javascript'
};
const host = {
console,
String,
Number,
Buffer,
Boolean,
Array,
Date,
Error,
RangeError,
ReferenceError,
SyntaxError,
TypeError,
RegExp,
Function,
Object,
VMError,
Proxy,
Reflect,
Map,
WeakMap,
Set,
WeakSet,
Promise
};
this._context = vm.createContext();
Reflect.defineProperty(this, '_internal', {
value: vm.runInContext(`(function(require, host) { ${cf} \n})`, this._context, {
filename: `${__dirname}/contextify.js`,
displayErrors: false
}).call(this._context, require, host)
});
// prepare global sandbox
if (this.options.sandbox) {
if ('object' !== typeof this.options.sandbox) {
throw new VMError("Sandbox must be object.");
}
for (let name in this.options.sandbox) {
this._internal.Contextify.globalValue(this.options.sandbox[name], name);
}
}
}
/**
* Freezes the object inside VM making it read-only. Not available for primitive values.
*
* @static
* @param {*} object Object to freeze.
* @param {String} [globalName] Whether to add the object to global.
* @return {*} Object to freeze.
*/
freeze(value, globalName) {
this._internal.Contextify.readonly(value);
if (global) this._internal.Contextify.globalValue(value, globalName);
return value;
}
/**
* Protects the object inside VM making impossible to set functions as it's properties. Not available for primitive values.
*
* @static
* @param {*} object Object to protect.
* @param {String} [globalName] Whether to add the object to global.
* @return {*} Object to protect.
*/
protect(value, globalName) {
this._internal.Contextify.protected(value);
if (global) this._internal.Contextify.globalValue(value, globalName);
return value;
}
/**
* Run the code in VM.
*
* @param {String} code Code to run.
* @return {*} Result of executed code.
*/
run(code) {
if (this.options.compiler !== 'javascript') {
code = _compileToJS(code, this.options.compiler);
}
const script = code instanceof VMScript ? code : new VMScript(code);
try {
return this._internal.Decontextify.value(script.compile()._compiled.runInContext(this._context, {
filename: script.filename,
displayErrors: false,
timeout: this.options.timeout
}));
} catch (e) {
throw this._internal.Decontextify.value(e);
}
}
}
n/a
class VMError extends Error {
/**
* Create VMError instance.
*
* @param {String} message Error message.
* @return {VMError}
*/
constructor(message) {
super(message);
this.name = 'VMError';
Error.captureStackTrace(this, this.constructor);
}
}
n/a
class VMScript {
/**
* Create VMScript instance.
*
* @param {String} code Code to run.
* @param {String} [filename] Filename that shows up in any stack traces produced from this script.
* @return {VMScript}
*/
constructor(code, filename) {
this.code = code;
this.filename = filename || 'vm.js';
}
/**
* Wraps the code.
*
* @return {VMScript}
*/
wrap(prefix, postfix) {
if (this._wrapped) return this;
this.code = prefix + this.code + postfix;
this._wrapped = true;
return this;
}
/**
* Compiles the code. If called multiple times, the code is only compiled once.
*
* @return {VMScript}
*/
compile() {
if (this._compiled) return this;
this._compiled = new vm.Script(this.code, {
filename: this.filename,
displayErrors: false
})
return this;
}
}
n/a
class NodeVM extends EventEmitter {
/**
* Create NodeVM instance.
*
* Unlike VM, NodeVM lets you use require same way like in regular node.
*
* @param {Object} [options] VM options.
* @return {NodeVM}
*/
constructor(options = {}) {
super();
// defaults
this.options = {
sandbox: options.sandbox != null ? options.sandbox : null,
console: options.console != null ? options.console : 'inherit',
require: options.require != null ? options.require : false,
compiler: options.compiler != null ? options.compiler : 'javascript',
require: options.require != null ? options.require : false,
nesting: options.nesting != null ? options.nesting : false,
wrapper: options.wrapper != null ? options.wrapper : 'commonjs'
};
const host = {
require,
process,
console,
setTimeout,
setInterval,
setImmediate,
clearTimeout,
clearInterval,
clearImmediate,
String,
Number,
Buffer,
Boolean,
Array,
Date,
Error,
RangeError,
ReferenceError,
SyntaxError,
TypeError,
RegExp,
Function,
Object,
VMError,
Proxy,
Reflect,
Map,
WeakMap,
Set,
WeakSet,
Promise
}
if (this.options.nesting) {
host.VM = VM;
host.NodeVM = NodeVM;
}
this._context = vm.createContext();
Object.defineProperty(this, '_internal', {
value: vm.runInContext(`(function(require, host) { ${cf} \n})`, this._context, {
filename: `${__dirname}/contextify.js`,
displayErrors: false
}).call(this._context, require, host)
})
const closure = vm.runInContext(`(function (vm, host, Contextify, Decontextify, Buffer) { ${sb} \n})`, this._context, {
filename: `${__dirname}/sandbox.js`,
displayErrors: false
})
Object.defineProperty(this, '_prepareRequire', {
value: closure.call(this._context, this, host, this._internal.Contextify, this._internal.Decontextify, this._internal.Buffer)
})
// prepare global sandbox
if (this.options.sandbox) {
if ('object' !== typeof this.options.sandbox) {
throw new VMError("Sandbox must be object.");
}
for (let name in this.options.sandbox) {
this._internal.Contextify.globalValue(this.options.sandbox[name], name);
}
}
if (this.options.require && this.options.require.import) {
if (!Array.isArray(this.options.require.import)) {
this.options.require.import = [this.options.require.import];
}
for (let i = 0, l = this.options.require.import.length; i < l; i++) {
this.require(this.options.require.import[i]);
}
}
}
/**
* @deprecated
*/
call(method, ...args) {
if ('function' === typeof method) {
return method.apply(args);
} else {
throw new VMError("Unrecognized method type.");
}
}
/**
* Freezes the object inside VM making it read-only. Not available for primitive values.
*
* @static
* @param {*} object Object to freeze.
* @param {String} [globalName] Whether to add the object to global.
* @return {*} Object to freeze.
*/
freeze(value, globalName) {
this._internal.Contextify.readonly(value);
if (global) this._internal.Contextify.globalValue(value, globalName);
return value;
}
/**
* Protects the object inside VM making impossible to set functions as it's properties. Not available for primitive values.
*
* @static
* @param {*} object Object to protect.
* @param {String} [globalName] Whether to add the object to global.
* @return {*} Object to protect.
*/
protect(value, globalName) {
this._internal.Contextify.protected(value);
if (global) this._internal.Contextify.globalValue(value, globalName);
return value;
}
/**
* Require a module in VM and return it's exports.
*
* @param {String} module Module name.
* @return {*} Exported module.
*/
require(module) {
return this.run(`module.exports = require('${module}');`, 'vm.js');
}
/**
* Run the code in NodeVM.
*
* First time you run this method, code is executed same way like in node's regular `require` - it's executed with `module`, `require
`, `exports`, `__dirname`, `__filename` variables and expect result in `mo ...
n/a
class VM extends EventEmitter {
/**
* Makes the object read only.
*
* @static
* @param {*} object Object to freeze.
* @return {*} Frozen object.
*/
/**
* Create VM instance.
*
* @param {Object} [options] VM options.
* @return {VM}
*/
constructor(options = {}) {
super();
// defaults
this.options = {
timeout: options.timeout != null ? options.timeout : undefined,
sandbox: options.sandbox != null ? options.sandbox : null,
compiler: options.compiler != null ? options.compiler : 'javascript'
};
const host = {
console,
String,
Number,
Buffer,
Boolean,
Array,
Date,
Error,
RangeError,
ReferenceError,
SyntaxError,
TypeError,
RegExp,
Function,
Object,
VMError,
Proxy,
Reflect,
Map,
WeakMap,
Set,
WeakSet,
Promise
};
this._context = vm.createContext();
Reflect.defineProperty(this, '_internal', {
value: vm.runInContext(`(function(require, host) { ${cf} \n})`, this._context, {
filename: `${__dirname}/contextify.js`,
displayErrors: false
}).call(this._context, require, host)
});
// prepare global sandbox
if (this.options.sandbox) {
if ('object' !== typeof this.options.sandbox) {
throw new VMError("Sandbox must be object.");
}
for (let name in this.options.sandbox) {
this._internal.Contextify.globalValue(this.options.sandbox[name], name);
}
}
}
/**
* Freezes the object inside VM making it read-only. Not available for primitive values.
*
* @static
* @param {*} object Object to freeze.
* @param {String} [globalName] Whether to add the object to global.
* @return {*} Object to freeze.
*/
freeze(value, globalName) {
this._internal.Contextify.readonly(value);
if (global) this._internal.Contextify.globalValue(value, globalName);
return value;
}
/**
* Protects the object inside VM making impossible to set functions as it's properties. Not available for primitive values.
*
* @static
* @param {*} object Object to protect.
* @param {String} [globalName] Whether to add the object to global.
* @return {*} Object to protect.
*/
protect(value, globalName) {
this._internal.Contextify.protected(value);
if (global) this._internal.Contextify.globalValue(value, globalName);
return value;
}
/**
* Run the code in VM.
*
* @param {String} code Code to run.
* @return {*} Result of executed code.
*/
run(code) {
if (this.options.compiler !== 'javascript') {
code = _compileToJS(code, this.options.compiler);
}
const script = code instanceof VMScript ? code : new VMScript(code);
try {
return this._internal.Decontextify.value(script.compile()._compiled.runInContext(this._context, {
filename: script.filename,
displayErrors: false,
timeout: this.options.timeout
}));
} catch (e) {
throw this._internal.Decontextify.value(e);
}
}
}
n/a
class VMError extends Error {
/**
* Create VMError instance.
*
* @param {String} message Error message.
* @return {VMError}
*/
constructor(message) {
super(message);
this.name = 'VMError';
Error.captureStackTrace(this, this.constructor);
}
}
n/a
class VMScript {
/**
* Create VMScript instance.
*
* @param {String} code Code to run.
* @param {String} [filename] Filename that shows up in any stack traces produced from this script.
* @return {VMScript}
*/
constructor(code, filename) {
this.code = code;
this.filename = filename || 'vm.js';
}
/**
* Wraps the code.
*
* @return {VMScript}
*/
wrap(prefix, postfix) {
if (this._wrapped) return this;
this.code = prefix + this.code + postfix;
this._wrapped = true;
return this;
}
/**
* Compiles the code. If called multiple times, the code is only compiled once.
*
* @return {VMScript}
*/
compile() {
if (this._compiled) return this;
this._compiled = new vm.Script(this.code, {
filename: this.filename,
displayErrors: false
})
return this;
}
}
n/a