isolated-vm
Advanced tools
Comparing version 1.1.0 to 1.2.0
{ | ||
"name": "isolated-vm", | ||
"version": "1.1.0", | ||
"version": "1.2.0", | ||
"description": "Access to multiple isolates", | ||
@@ -5,0 +5,0 @@ "main": "isolated-vm.js", |
@@ -7,3 +7,6 @@ [](https://www.npmjs.com/package/isolated-vm) [](https://github.com/laverdet/isolated-vm/blob/master/LICENSE) [](https://travis-ci.org/laverdet/isolated-vm) | ||
`isolated-vm` is a library for nodejs which gives you access to v8's `Isolate` interface. This | ||
allows you to create JavaScript environments which are completely *isolated* from each other. | ||
allows you to create JavaScript environments which are completely *isolated* from each other. You | ||
might find this module useful if you need to run some untrusted code in a secure way. You may also | ||
find this module useful if you need to run some JavaScript simultaneously in multiple threads. You | ||
may find this project *very* useful if you need to do both at the same time! | ||
@@ -13,8 +16,8 @@ API DOCUMENTATION | ||
Since isolates share no resources with each other, the primary goal of this API is to provide | ||
primitives which make marshalling data between many isolates quick and easy. The only way to pass | ||
data from one isolate to another is to first make that data *transferable*. Primitives (except for | ||
`Symbol`) are always transferable. This means if you invoke a function in a different isolate with a | ||
number or string as the argument, it will work fine. If you need to pass more complex information | ||
you will have to first make the data transferable with one of the methods here. | ||
Since isolates share no resources with each other, most of this API is built to provide primitives | ||
which make marshalling data between many isolates quick and easy. The only way to pass data from one | ||
isolate to another is to first make that data *transferable*. Primitives (except for `Symbol`) are | ||
always transferable. This means if you invoke a function in a different isolate with a number or | ||
string as the argument, it will work fine. If you need to pass more complex information you will | ||
have to first make the data transferable with one of the methods here. | ||
@@ -25,16 +28,23 @@ Most methods will provide both a synchronous and an asynchronous version. Calling the synchronous | ||
[Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) | ||
while the work runs in a separate thread pool. I recommend deciding which version of the API is the | ||
best for your project and sticking to it throughout your code, i.e. don't mix and match async/sync | ||
code. The only strict technical limitation, though, is that you may not call a synchronous method | ||
from within a asynchronous method. | ||
while the work runs in a separate thread pool. | ||
There are some rules about which functions may be called from certain contexts: | ||
1. Asynchronous functions may be called at any time | ||
2. Synchronous functions usually may not be called from an asynchronous function | ||
3. You may call a synchronous function from an asynchronous function as long as that function | ||
belongs to current isolate | ||
4. You may call a synchronous function belonging to the default nodejs isolate at any time | ||
Additionally, some methods will provide an "ignored" version which runs asynchronously but returns | ||
no promise. This can be a good option when the calling isolate would ignore the promise anyway, | ||
since the ignored versions can skip an extra thread synchronization. Just be careful because this | ||
swallows any thrown exceptions which might make problems hard to track down. It's also worth noting | ||
that all asynchronous invocations will run in the order they were queued, regardless of whether or | ||
not you wait on them. So, for instance, you could call several "ignored" methods in a row and then | ||
`await` on a final async method to observe some side-effect of the ignored methods. | ||
swallows any thrown exceptions which might make problems hard to track down. | ||
It's also worth noting that all asynchronous invocations will run in the order they were queued, | ||
regardless of whether or not you wait on them. So, for instance, you could call several "ignored" | ||
methods in a row and then `await` on a final async method to observe some side-effect of the | ||
ignored methods. | ||
### Class: `Isolate` *[transferable]* | ||
@@ -121,7 +131,6 @@ This is the main reference to an isolate. Every handle to an isolate is transferable, which means | ||
##### `context.globalReference()` | ||
* **return** A [`Reference`](#class-reference-transferable) object. | ||
##### `context.global` *[`Reference`](#class-reference-transferable)* | ||
[`Reference`](#class-reference-transferable) to this context's global object. Note that if you call | ||
`context.release()` the global reference will be released as well. | ||
Returns a [`Reference`](#class-reference-transferable) to this context's global object. | ||
##### `context.release()` | ||
@@ -210,2 +219,3 @@ | ||
##### `reference.applySync(receiver, arguments)` | ||
##### `reference.applySyncPromise(receiver, arguments)` | ||
* `receiver` *[transferable]* - The value which will be `this`. | ||
@@ -219,4 +229,13 @@ * `arguments` *[array]* - Array of transferables which will be passed to the function. | ||
Will attempt to invoke an object as if it were a function. If the return value is transferable it | ||
will be returned to the called of `apply`, otherwise an error will be thrown. | ||
will be returned to the caller of `apply`, otherwise an error will be thrown. | ||
`applySyncPromise` is a special version of `applySync` which may only be invoked on functions | ||
belonging to the default isolate AND may only be invoked from a non-default thread. Functions | ||
invoked in this way may return a promise and the invoking isolate will wait for that promise to | ||
resolve before resuming execution. You can use this to implement functions like `readFileSync` in a | ||
way that doesn't block the default isolate. Note that the invoking isolate will not respond to any | ||
async functions until this promise is resolved, however synchronous functions will still function | ||
correctly. Misuse of this feature may result in deadlocked isolates, though the default isolate | ||
will never be at risk of a deadlock. | ||
### Class: `ExternalCopy` *[transferable]* | ||
@@ -290,3 +309,3 @@ Instances of this class represent some value that is stored outside of any v8 isolate. This value | ||
// Get a Reference{} to the global object within the context. | ||
let jail = context.globalReference(); | ||
let jail = context.global; | ||
@@ -393,6 +412,5 @@ // This make the global object available in the context as `global`. We use `derefInto()` here | ||
let context = await isolate.createContext(); | ||
let jail = context.globalReference(); | ||
let script = await isolate.compileScript(sum+ ''); | ||
await script.run(context); | ||
let fnReference = await jail.get('sum'); | ||
let fnReference = await context.global.get('sum'); | ||
@@ -399,0 +417,0 @@ // Run one slice of the sum loop |
@@ -14,2 +14,11 @@ 'use strict'; | ||
{ | ||
// ArrayBuffer::New will crash if the allocator fails | ||
let isolate = new ivm.Isolate({ memoryLimit: 16 }); | ||
let array = new ivm.ExternalCopy(new Uint8Array(1024 * 1024 * 16)); | ||
try { | ||
isolate.createContextSync().global.setSync('a', array.copyInto()); | ||
} catch (err) {} | ||
} | ||
// Test transfer out | ||
@@ -61,3 +70,3 @@ { | ||
let isolate = new ivm.Isolate; | ||
let global = isolate.createContextSync().globalReference(); | ||
let global = isolate.createContextSync().global; | ||
global.setSync('foo', copy2.copyInto({ transferIn: true })); | ||
@@ -64,0 +73,0 @@ try { |
@@ -9,6 +9,5 @@ 'use strict'; | ||
let context = isolate.createContextSync(); | ||
let global = context.globalReference(); | ||
global.release(); | ||
let global = context.global; | ||
context.release(); | ||
} | ||
console.log('pass'); |
@@ -6,3 +6,3 @@ let ivm = require('isolated-vm'); | ||
let context = isolate.createContextSync(); | ||
let global = context.globalReference(); | ||
let global = context.global; | ||
global.setSync('ivm', ivm); | ||
@@ -9,0 +9,0 @@ isolate.compileScriptSync(` |
@@ -7,3 +7,3 @@ // Create a new isolate limited to 128MB | ||
let context = isolate.createContextSync(); | ||
let jail = context.globalReference(); | ||
let jail = context.global; | ||
jail.setSync('global', jail.derefInto()); | ||
@@ -10,0 +10,0 @@ isolate.compileScriptSync('new '+ function() { |
@@ -7,3 +7,3 @@ 'use strict'; | ||
let context = isolate.createContextSync(); | ||
let global = context.globalReference(); | ||
let global = context.global; | ||
let script = isolate.compileScriptSync('isolate.dispose()'); | ||
@@ -10,0 +10,0 @@ return { isolate, context, global, script }; |
@@ -9,3 +9,3 @@ 'use strict'; | ||
let context = isolate.createContextSync(); | ||
let global = context.globalReference(); | ||
let global = context.global; | ||
return { isolate, context, global }; | ||
@@ -12,0 +12,0 @@ }); |
@@ -5,3 +5,3 @@ 'use strict'; | ||
let context = isolate.createContextSync(); | ||
let global = context.globalReference(); | ||
let global = context.global; | ||
@@ -8,0 +8,0 @@ let kb1 = '................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................'; |
@@ -19,3 +19,3 @@ 'use strict'; | ||
let context = isolate.createContextSync(); | ||
context.globalReference().setSync('wait', new ivm.Reference(function() {})); | ||
context.global.setSync('wait', new ivm.Reference(function() {})); | ||
isolate.compileScriptSync(src).run(context).catch(function() { | ||
@@ -28,3 +28,3 @@ let timeTaken = Date.now() - time; | ||
let context = isolate.createContextSync(); | ||
context.globalReference().setSync('wait', new ivm.Reference(function(a) { | ||
context.global.setSync('wait', new ivm.Reference(function(a) { | ||
while (Date.now() < runUntil); | ||
@@ -31,0 +31,0 @@ })); |
@@ -17,3 +17,3 @@ 'use strict'; | ||
let context = isolate.createContextSync(); | ||
let global = context.globalReference(); | ||
let global = context.global; | ||
try { | ||
@@ -20,0 +20,0 @@ for (let ii = 0; ii < 256; ++ii) { |
let ivm = require('isolated-vm'); | ||
let isolate = new ivm.Isolate({ memoryLimit: 32 }); | ||
let context = isolate.createContextSync(); | ||
let global = context.globalReference(); | ||
let global = context.global; | ||
global.setSync('blob', new ivm.ExternalCopy({ val: `[${Array(Math.floor(1024 * 1024 * 32 / 12)).fill('"aa"').join(',')}]` }).copyInto()); | ||
@@ -6,0 +6,0 @@ |
@@ -6,3 +6,3 @@ 'use strict'; | ||
let context = isolate.createContextSync(); | ||
let jail = context.globalReference(); | ||
let jail = context.global; | ||
jail.setSync('context', context); | ||
@@ -43,3 +43,3 @@ jail.setSync('isolate', isolate); | ||
} | ||
let ref = context.globalReference().getSync('sabotage'); | ||
let ref = context.global.getSync('sabotage'); | ||
ref.applySync(undefined, []); | ||
@@ -46,0 +46,0 @@ }); |
@@ -41,3 +41,3 @@ 'use strict'; | ||
try { | ||
context.globalReference().getSync('load').applySync(null, [ ii ]); | ||
context.global.getSync('load').applySync(null, [ ii ]); | ||
return false; | ||
@@ -62,3 +62,3 @@ } catch (err) { | ||
try { | ||
context.globalReference().getSync('loadAndCopy').applySync(null, [ failure - 1024, new ivm.ExternalCopy(overflow) ]); | ||
context.global.getSync('loadAndCopy').applySync(null, [ failure - 1024, new ivm.ExternalCopy(overflow) ]); | ||
console.log('did not fail?'); | ||
@@ -65,0 +65,0 @@ } catch (err) { |
@@ -6,3 +6,3 @@ 'use strict'; | ||
let context = isolate.createContextSync(); | ||
let global = context.globalReference(); | ||
let global = context.global; | ||
global.setSync('global', global.derefInto()); | ||
@@ -9,0 +9,0 @@ let script = isolate.compileScriptSync(` |
@@ -5,3 +5,3 @@ // Create a new isolate limited to 128MB | ||
let context = isolate.createContextSync(); | ||
let jail = context.globalReference(); | ||
let jail = context.global; | ||
jail.setSync('lib', ivm.lib); | ||
@@ -8,0 +8,0 @@ isolate.compileScriptSync('new '+ function() { |
@@ -7,3 +7,3 @@ 'use strict'; | ||
let script = await isolate.compileScript('foo + 1 == bar ? "pass" : "fail"'); | ||
let global = context.globalReference(); | ||
let global = context.global; | ||
if (global.setIgnored('foo', 1) || global.setIgnored('bar', 2)) { | ||
@@ -10,0 +10,0 @@ console.log('fail'); |
let ivm = require('isolated-vm'); | ||
let isolate = new ivm.Isolate; | ||
let context = isolate.createContextSync(); | ||
let global = context.globalReference(); | ||
let global = context.global; | ||
@@ -6,0 +6,0 @@ function recur1() { |
@@ -15,3 +15,3 @@ 'use strict'; | ||
let context = isolate.createContextSync(); | ||
let global = context.globalReference(); | ||
let global = context.global; | ||
return { isolate, context, global }; | ||
@@ -18,0 +18,0 @@ } |
@@ -6,3 +6,3 @@ // Create a new isolate limited to 128MB | ||
let context = isolate.createContextSync(); | ||
let jail = context.globalReference(); | ||
let jail = context.global; | ||
jail.setSync('context', context); | ||
@@ -9,0 +9,0 @@ jail.setSync('isolate', isolate); |
@@ -7,3 +7,3 @@ 'use strict'; | ||
let context = isolate.createContextSync(); | ||
let global = context.globalReference(); | ||
let global = context.global; | ||
global.setSync('global', global.derefInto()); | ||
@@ -10,0 +10,0 @@ isolate.compileScriptSync('global.run = () => { for(;;); }').runSync(context); |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
295610
100
1509
450
6