Skip to content

Commit c05936c

Browse files
amb26bnoordhuis
authored andcommitted
vm: fix incorrect dispatch of vm.runInContext for argument "filename"
Adds test case and documentation for vm.runInContext and vm.createContext. Fixes nodejs#1140.
1 parent 72246d9 commit c05936c

3 files changed

Lines changed: 52 additions & 1 deletion

File tree

doc/api/vm.markdown

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,45 @@ requires a separate process.
6565
In case of syntax error in `code`, `vm.runInNewContext` emits the syntax error to stderr
6666
and throws an exception.
6767

68+
### vm.runInContext(code, context, [filename])
69+
70+
`vm.runInContext` compiles `code` to run in context `context` as if it were loaded from `filename`,
71+
then runs it and returns the result. A (V8) context comprises a global object, together with a
72+
set of built-in objects and functions. Running code does not have access to local scope and
73+
the global object held within `context` will be used as the global object for `code`.
74+
`filename` is optional.
75+
76+
Example: compile and execute code in a existing context.
77+
78+
var util = require('util'),
79+
vm = require('vm'),
80+
initSandbox = {
81+
animal: 'cat',
82+
count: 2
83+
},
84+
context = vm.createContext(initSandbox);
85+
86+
vm.runInContext('count += 1; name = "CATT"', context, 'myfile.vm');
87+
console.log(util.inspect(context));
88+
89+
// { animal: 'cat', count: 3, name: 'CATT' }
90+
91+
Note that `createContext` will perform a shallow clone of the supplied sandbox object in order to
92+
initialise the global object of the freshly constructed context.
93+
94+
Note that running untrusted code is a tricky business requiring great care. To prevent accidental
95+
global variable leakage, `vm.runInContext` is quite useful, but safely running untrusted code
96+
requires a separate process.
97+
98+
In case of syntax error in `code`, `vm.runInContext` emits the syntax error to stderr
99+
and throws an exception.
100+
101+
### vm.createContext([initSandbox])
102+
103+
`vm.createContext` creates a new context which is suitable for use as the 2nd argument of a subsequent
104+
call to `vm.runInContext`. A (V8) context comprises a global object together with a set of
105+
build-in objects and functions. The optional argument `initSandbox` will be shallow-copied
106+
to seed the initial contents of the global object used by the context.
68107

69108
### vm.createScript(code, [filename])
70109

src/node_script.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -308,7 +308,7 @@ Handle<Value> WrappedScript::EvalMachine(const Arguments& args) {
308308
}
309309

310310
const int filename_index = sandbox_index +
311-
(context_flag == newContext ? 1 : 0);
311+
(context_flag == thisContext? 0 : 1);
312312
Local<String> filename = args.Length() > filename_index
313313
? args[filename_index]->ToString()
314314
: String::New("evalmachine.<anonymous>");

test/simple/test-script-context.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,18 @@ assert.equal('lala', context.thing);
4646
// Issue GH-227:
4747
Script.runInNewContext('', null, 'some.js');
4848

49+
// Issue GH-1140:
50+
common.debug('test runInContext signature');
51+
var gh1140Exception;
52+
try {
53+
Script.runInContext('throw new Error()', context, 'expected-filename.js');
54+
}
55+
catch (e) {
56+
gh1140Exception = e;
57+
assert.ok(/expected-filename/.test(e.stack), 'expected appearance of filename in Error stack');
58+
}
59+
assert.ok(gh1140Exception, 'expected exception from runInContext signature test');
60+
4961
// GH-558, non-context argument segfaults / raises assertion
5062
function isTypeError(o) {
5163
return o instanceof TypeError;

0 commit comments

Comments
 (0)