Comparing version 3.1.0 to 3.2.0
@@ -6,3 +6,3 @@ 'use strict' | ||
// global is originally prototype of host.Object so it can be used to climu up from the sandbox. | ||
// global is originally prototype of host.Object so it can be used to climb up from the sandbox. | ||
Object.setPrototypeOf(global, Object.prototype); | ||
@@ -167,13 +167,13 @@ | ||
return host.Object.defineProperty(target, key, { | ||
get: Contextify.value(def.get, deepTraps) || undefined, | ||
set: Contextify.value(def.set, deepTraps) || undefined, | ||
enumerable: def.enumerable === true, | ||
configurable: def.configurable === true | ||
get: Contextify.value(descriptor.get, deepTraps) || undefined, | ||
set: Contextify.value(descriptor.set, deepTraps) || undefined, | ||
enumerable: descriptor.enumerable === true, | ||
configurable: descriptor.configurable === true | ||
}) | ||
} else { | ||
return host.Object.defineProperty(target, key, { | ||
value: Contextify.value(def.value, deepTraps), | ||
writable: def.writable === true, | ||
enumerable: def.enumerable === true, | ||
configurable: def.configurable === true | ||
value: Contextify.value(descriptor.value, deepTraps), | ||
writable: descriptor.writable === true, | ||
enumerable: descriptor.enumerable === true, | ||
configurable: descriptor.configurable === true | ||
}) | ||
@@ -369,13 +369,13 @@ } | ||
return host.Object.defineProperty(target, key, { | ||
get: Decontextify.value(def.get, deepTraps) || undefined, | ||
set: Decontextify.value(def.set, deepTraps) || undefined, | ||
enumerable: def.enumerable === true, | ||
configurable: def.configurable === true | ||
get: Decontextify.value(descriptor.get, deepTraps) || undefined, | ||
set: Decontextify.value(descriptor.set, deepTraps) || undefined, | ||
enumerable: descriptor.enumerable === true, | ||
configurable: descriptor.configurable === true | ||
}) | ||
} else { | ||
return host.Object.defineProperty(target, key, { | ||
value: Decontextify.value(def.value, deepTraps), | ||
writable: def.writable === true, | ||
enumerable: def.enumerable === true, | ||
configurable: def.configurable === true | ||
value: Decontextify.value(descriptor.value, deepTraps), | ||
writable: descriptor.writable === true, | ||
enumerable: descriptor.enumerable === true, | ||
configurable: descriptor.configurable === true | ||
}) | ||
@@ -382,0 +382,0 @@ } |
@@ -31,2 +31,31 @@ const fs = require('fs'); | ||
/** | ||
* Class Script | ||
*/ | ||
class VMScript { | ||
constructor(code, filename) { | ||
this.code = code; | ||
this.filename = filename || 'vm.js'; | ||
} | ||
wrap(prefix, postfix) { | ||
if (this._wrapped) return this; | ||
this.code = prefix + this.code + postfix; | ||
this._wrapped = true; | ||
return this; | ||
} | ||
compile() { | ||
if (this._compiled) return this; | ||
this._compiled = new vm.Script(this.code, { | ||
filename: this.filename, | ||
displayErrors: false | ||
}) | ||
return this; | ||
} | ||
} | ||
/** | ||
* Class VM. | ||
@@ -113,11 +142,8 @@ * | ||
} | ||
let script = code instanceof VMScript ? code : new VMScript(code); | ||
let script = new vm.Script(code, { | ||
filename: "vm.js", | ||
displayErrors: false | ||
}); | ||
try { | ||
return this._internal.Decontextify.value(script.runInContext(this._context, { | ||
filename: "vm.js", | ||
return this._internal.Decontextify.value(script.compile()._compiled.runInContext(this._context, { | ||
filename: script.filename, | ||
displayErrors: false, | ||
@@ -291,11 +317,9 @@ timeout: this.options.timeout | ||
}); | ||
let script = code instanceof VMScript ? code : new VMScript(code, filename); | ||
script.wrap('(function (exports, require, module, __filename, __dirname) { ', ' \n})'); | ||
let script = new vm.Script(`(function (exports, require, module, __filename, __dirname) { ${code} \n})`, { | ||
filename: filename || "vm.js", | ||
displayErrors: false | ||
}); | ||
try { | ||
let closure = script.runInContext(this._context, { | ||
filename: filename || "vm.js", | ||
let closure = script.compile()._compiled.runInContext(this._context, { | ||
filename: script.filename, | ||
displayErrors: false | ||
@@ -391,1 +415,2 @@ }); | ||
exports.VM = VM; | ||
exports.VMScript = VMScript; |
@@ -16,3 +16,3 @@ { | ||
], | ||
"version": "3.1.0", | ||
"version": "3.2.0", | ||
"main": "index.js", | ||
@@ -19,0 +19,0 @@ "repository": { |
@@ -1,2 +0,2 @@ | ||
# vm2 [![NPM Version][npm-image]][npm-url] [![Package Quality][quality-image]][quality-url] [![Travis CI][travis-image]][travis-url] | ||
# 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] | ||
@@ -12,4 +12,4 @@ vm2 is a sandbox that can run untrusted code with whitelisted Node's built-in modules. Securely! | ||
* You can limit access to certain (or all) builtin modules | ||
* You can securely call methods and exchange data and callback between sandboxes | ||
* Is immune to `while (true) {}` (VM only, see docs) | ||
* You can securely call methods and exchange data and callbacks between sandboxes | ||
* Is immune to `while (true) {}` (see docs) | ||
* Is immune to all known methods of attacks | ||
@@ -21,3 +21,3 @@ * Transpilers support | ||
* It uses internal VM module to create secure context | ||
* It uses [Proxies](https://developer.mozilla.org/cs/docs/Web/JavaScript/Reference/Global_Objects/Proxy) to prevent escaping the sandbox | ||
* It uses [Proxies](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Proxy) to prevent escaping the sandbox | ||
* It overrides builtin require to control access to modules | ||
@@ -63,2 +63,3 @@ | ||
* [NodeVM](#nodevm) | ||
* [VMScript](#vmscript) | ||
* [Cross-sandbox relationships](#cross-sandbox-relationships) | ||
@@ -142,4 +143,13 @@ * [CLI](#cli) | ||
// Sync | ||
let functionInSandbox = vm.run("module.exports = function(who) { console.log('hello '+ who); }"); | ||
functionInSandbox('world'); | ||
// Async | ||
let functionWithCallbackInSandbox = vm.run("module.exports = function(who, callback) { callback('hello '+ who); }"); | ||
functionWithCallbackInSandbox('world', (greeting) => { | ||
console.log(greeting); | ||
}); | ||
``` | ||
@@ -163,2 +173,50 @@ | ||
## VMScript | ||
You can increase performance by using pre-compiled scripts. The pre-compiled VMScript can be run later multiple times. It is important to note that the code is not bound to any VM (context); rather, it is bound before each run, just for that run. | ||
```javascript | ||
const {VM, VMScript} = require('vm2'); | ||
const vm = new VM(); | ||
const script = new VMScript("Math.random()"); | ||
console.log(vm.run(script)); | ||
console.log(vm.run(script)); | ||
``` | ||
Works for both `VM` and `NodeVM`. | ||
```javascript | ||
const {NodeVM, VMScript} = require('vm2'); | ||
const vm = new NodeVM(); | ||
const script = new VMScript("module.exports = Math.random()"); | ||
console.log(vm.run(script)); | ||
console.log(vm.run(script)); | ||
``` | ||
Code is compiled automatically first time you run it. You can compile the code anytime with `script.compile()`. Once the code is compiled, the method has no effect. | ||
## Error handling | ||
Errors in code compilation and synchronous code execution can be handled by `try`/`catch`. Errors in asynchronous code execution can be handled by attaching `uncaughtException` event handler to Node's `process`. | ||
```javascript | ||
try { | ||
var script = new VMScript("Math.random()").compile(); | ||
} catch (err) { | ||
console.error('Failed to compile script.', err); | ||
} | ||
try { | ||
vm.run(script); | ||
} catch (err) { | ||
console.error('Failed to execute script.', err); | ||
} | ||
process.on('uncaughtException', (err) => { | ||
console.error('Asynchronous error caught.', err); | ||
}) | ||
``` | ||
## Cross-sandbox relationships | ||
@@ -216,5 +274,9 @@ | ||
## Sponsors | ||
Development is sponsored by [Integromat](https://www.integromat.com). | ||
## License | ||
Copyright (c) 2014-2016 Patrik Simek | ||
Copyright (c) 2014-2017 Patrik Simek | ||
@@ -231,2 +293,4 @@ The MIT License | ||
[npm-url]: https://www.npmjs.com/package/vm2 | ||
[downloads-image]: https://img.shields.io/npm/dm/vm2.svg?style=flat-square | ||
[downloads-url]: https://www.npmjs.com/package/vm2 | ||
[quality-image]: http://npm.packagequality.com/shield/vm2.svg?style=flat-square | ||
@@ -233,0 +297,0 @@ [quality-url]: http://packagequality.com/#?package=vm2 |
const assert = require("assert"); | ||
const {NodeVM, VM} = require('..'); | ||
const {NodeVM, VM, VMScript} = require('..'); | ||
@@ -715,1 +715,25 @@ global.isVM = false; | ||
}) | ||
describe('precompiled scripts', () => { | ||
it('VM', done => { | ||
let vm = new VM(); | ||
let script = new VMScript("Math.random()"); | ||
let val1 = vm.run(script); | ||
let val2 = vm.run(script); | ||
assert.ok('number' === typeof val1 && 'number' === typeof val2); | ||
assert.ok( val1 != val2); | ||
done() | ||
}) | ||
it('NodeVM', done => { | ||
let vm = new NodeVM(); | ||
let script = new VMScript("module.exports = Math.random()"); | ||
let val1 = vm.run(script); | ||
let val2 = vm.run(script); | ||
assert.ok('number' === typeof val1 && 'number' === typeof val2); | ||
assert.ok( val1 != val2); | ||
done() | ||
}) | ||
}) |
Sorry, the diff of this file is not supported yet
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
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
68097
14
1712
293