From c05936ca13681059c7aeecfe3a608e4e1afa800a Mon Sep 17 00:00:00 2001 From: Antranig Basman Date: Thu, 2 Jun 2011 13:45:30 -0600 Subject: [PATCH] vm: fix incorrect dispatch of vm.runInContext for argument "filename" Adds test case and documentation for vm.runInContext and vm.createContext. Fixes #1140. --- doc/api/vm.markdown | 39 ++++++++++++++++++++++++++++++ src/node_script.cc | 2 +- test/simple/test-script-context.js | 12 +++++++++ 3 files changed, 52 insertions(+), 1 deletion(-) diff --git a/doc/api/vm.markdown b/doc/api/vm.markdown index 2b7869da49f..d3e3606ef2f 100644 --- a/doc/api/vm.markdown +++ b/doc/api/vm.markdown @@ -65,6 +65,45 @@ requires a separate process. In case of syntax error in `code`, `vm.runInNewContext` emits the syntax error to stderr and throws an exception. +### vm.runInContext(code, context, [filename]) + +`vm.runInContext` compiles `code` to run in context `context` as if it were loaded from `filename`, +then runs it and returns the result. A (V8) context comprises a global object, together with a +set of built-in objects and functions. Running code does not have access to local scope and +the global object held within `context` will be used as the global object for `code`. +`filename` is optional. + +Example: compile and execute code in a existing context. + + var util = require('util'), + vm = require('vm'), + initSandbox = { + animal: 'cat', + count: 2 + }, + context = vm.createContext(initSandbox); + + vm.runInContext('count += 1; name = "CATT"', context, 'myfile.vm'); + console.log(util.inspect(context)); + + // { animal: 'cat', count: 3, name: 'CATT' } + +Note that `createContext` will perform a shallow clone of the supplied sandbox object in order to +initialise the global object of the freshly constructed context. + +Note that running untrusted code is a tricky business requiring great care. To prevent accidental +global variable leakage, `vm.runInContext` is quite useful, but safely running untrusted code +requires a separate process. + +In case of syntax error in `code`, `vm.runInContext` emits the syntax error to stderr +and throws an exception. + +### vm.createContext([initSandbox]) + +`vm.createContext` creates a new context which is suitable for use as the 2nd argument of a subsequent +call to `vm.runInContext`. A (V8) context comprises a global object together with a set of +build-in objects and functions. The optional argument `initSandbox` will be shallow-copied +to seed the initial contents of the global object used by the context. ### vm.createScript(code, [filename]) diff --git a/src/node_script.cc b/src/node_script.cc index 6c1099c0720..4f4153caa98 100644 --- a/src/node_script.cc +++ b/src/node_script.cc @@ -308,7 +308,7 @@ Handle WrappedScript::EvalMachine(const Arguments& args) { } const int filename_index = sandbox_index + - (context_flag == newContext ? 1 : 0); + (context_flag == thisContext? 0 : 1); Local filename = args.Length() > filename_index ? args[filename_index]->ToString() : String::New("evalmachine."); diff --git a/test/simple/test-script-context.js b/test/simple/test-script-context.js index 3d054b7b7d1..fe6b9b68c51 100644 --- a/test/simple/test-script-context.js +++ b/test/simple/test-script-context.js @@ -46,6 +46,18 @@ assert.equal('lala', context.thing); // Issue GH-227: Script.runInNewContext('', null, 'some.js'); +// Issue GH-1140: +common.debug('test runInContext signature'); +var gh1140Exception; +try { + Script.runInContext('throw new Error()', context, 'expected-filename.js'); +} +catch (e) { + gh1140Exception = e; + assert.ok(/expected-filename/.test(e.stack), 'expected appearance of filename in Error stack'); +} +assert.ok(gh1140Exception, 'expected exception from runInContext signature test'); + // GH-558, non-context argument segfaults / raises assertion function isTypeError(o) { return o instanceof TypeError;