From fc83002a7a8b2b96a5fdfe5fd9b99ca0391945e7 Mon Sep 17 00:00:00 2001 From: Antranig Basman Date: Thu, 2 Jun 2011 13:45:30 -0600 Subject: [PATCH 1/3] Node issue #1140: Fix incorrect dispatch of vm.runInContext for argument "filename" --- src/node_script.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/node_script.cc b/src/node_script.cc index ce7761d0c26..c91ca4a3b4f 100644 --- a/src/node_script.cc +++ b/src/node_script.cc @@ -297,7 +297,7 @@ Handle WrappedScript::EvalMachine(const Arguments& args) { } const int filename_index = sandbox_index + - (context_flag == newContext ? 1 : 0); + ((context_flag == newContext || context_flag == userContext)? 1 : 0); Local filename = args.Length() > filename_index ? args[filename_index]->ToString() : String::New("evalmachine."); From 1bc05b635b6818ff4df74a10ff7617b4900124ad Mon Sep 17 00:00:00 2001 From: Antranig Basman Date: Fri, 3 Jun 2011 22:30:01 -0600 Subject: [PATCH 2/3] NODE-1140: Added test case and documentation update for vm.runInContext method --- doc/api/vm.markdown | 33 ++++++++++++++++++++++++++++++ test/simple/test-script-context.js | 10 +++++++++ 2 files changed, 43 insertions(+) diff --git a/doc/api/vm.markdown b/doc/api/vm.markdown index 2b7869da49f..d05fa4d186f 100644 --- a/doc/api/vm.markdown +++ b/doc/api/vm.markdown @@ -65,6 +65,39 @@ 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.createScript(code, [filename]) diff --git a/test/simple/test-script-context.js b/test/simple/test-script-context.js index a7f853797fa..f52fa127061 100644 --- a/test/simple/test-script-context.js +++ b/test/simple/test-script-context.js @@ -44,3 +44,13 @@ assert.equal('lala', context.thing); // Issue GH-227: Script.runInNewContext('', null, 'some.js'); + +// Issue GH-1140: +common.debug('test runInContext signature'); +try { + Script.runInContext('throw new Error()', context, 'expected-filename.js'); +} +catch (e) { + common.debug("Got stack " + e.stack); + assert.ok(/expected-filename/.test(e.stack), 'expected appearance of filename in Error stack'); +} \ No newline at end of file From 3cf98c475794d696cf787d638dec00dde3bbc107 Mon Sep 17 00:00:00 2001 From: Antranig Basman Date: Mon, 15 Aug 2011 19:06:15 -0600 Subject: [PATCH 3/3] GH-1140: Fixes to impl, test and docs following code review --- doc/api/vm.markdown | 10 ++++++++-- src/node_script.cc | 2 +- test/simple/test-script-context.js | 6 ++++-- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/doc/api/vm.markdown b/doc/api/vm.markdown index d05fa4d186f..d3e3606ef2f 100644 --- a/doc/api/vm.markdown +++ b/doc/api/vm.markdown @@ -67,7 +67,7 @@ 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`, +`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`. @@ -93,11 +93,17 @@ 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. +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 c91ca4a3b4f..d83dfe185f3 100644 --- a/src/node_script.cc +++ b/src/node_script.cc @@ -297,7 +297,7 @@ Handle WrappedScript::EvalMachine(const Arguments& args) { } const int filename_index = sandbox_index + - ((context_flag == newContext || context_flag == userContext)? 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 f52fa127061..6f02d3910df 100644 --- a/test/simple/test-script-context.js +++ b/test/simple/test-script-context.js @@ -47,10 +47,12 @@ 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) { - common.debug("Got stack " + e.stack); + gh1140Exception = e; assert.ok(/expected-filename/.test(e.stack), 'expected appearance of filename in Error stack'); -} \ No newline at end of file +} +assert.ok(gh1140Exception, 'expected exception from runInContext signature test');