-
Notifications
You must be signed in to change notification settings - Fork 30.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
vm.runInThisContext is bound to the top context #14757
Comments
Lightly tested but this patch should fix it.
diff --git a/src/node_contextify.cc b/src/node_contextify.cc
index 792b1c4f80..931e3ee824 100644
--- a/src/node_contextify.cc
+++ b/src/node_contextify.cc
@@ -643,6 +643,10 @@ class ContextifyScript : public BaseObject {
bool display_errors = maybe_display_errors.ToChecked();
bool break_on_sigint = maybe_break_on_sigint.ToChecked();
+ auto context = args.GetIsolate()->GetEnteredContext();
+ if (context.IsEmpty()) context = env->context();
+ Context::Scope context_scope(context);
+
// Do the eval within this context
EvalMachine(env, timeout, display_errors, break_on_sigint, args,
&try_catch); |
@bnoordhuis That does fix the OP, but not this one: 'use strict';
const vm = require('vm');
const context = vm.createContext({
status: 'inside',
runInThisContext: vm.runInThisContext
});
global.status = 'outside';
console.log(vm.runInContext('eval', context)("runInThisContext('status')")); Is it possible to actually fix this? |
I think #14757 (comment) is helpful, even if it does not completely fix the problem. @bnoordhuis are you interested in submitting it as a PR? |
There is good news and bad news. The good news is that the patch fixes not just the original bug report but also the known_issues test for #7788 and a stdio redirection bug in the REPL. The bad news is that #14757 (comment) is a special case of this, which makes it a regression of the two steps forward, one step back variety. // Refs: https://github.com/nodejs/node/issues/14757
'use strict';
const common = require('../common');
const assert = require('assert');
const vm = require('vm');
{
const s = '(function() { return [this, runInThisContext("this")] })';
const f = vm.runInNewContext(s, vm);
const [that0, that1] = f();
assert.strictEqual(that0, that1);
assert.notEqual(that0, global);
} I think it could be solved if you knew what context the caller of V8 had an API at one time to retrieve the Alternatively, we could store the script ids of each context and map them back with |
Change `vm.runInThisContext()` to use the last entered context, not the top-level context that `vm.runInThisContext()` belongs to. Note the call chain: 1. `node::ContextifyScript::RunInThisContext()` 2. `node::ContextifyScript::EvalMachine()` 3. `v8::Script::BindToCurrentContext()` The current context in `RunInThisContext()` is that of the top-level context which was then bound to the script to execute. It works when `vm.runInThisContext()` is called from the top-level context (the common case and hence why this bug went unnoticed for so long) but not when called from an inferior context. As a pleasant side effect, this commit fixes a bug in the REPL where writes to `process.stdout` and `process.stderr` still went to the real stdout and stderr instead of being captured redirected. Fixes previously failing test `known_issues/test-repl-require-context` which has been moved to `test/parallel` and renamed to avoid a conflict with an existing test of the same name. Note that this commit changes the behavior of the following snippet: const s = '(function() { return vm.runInThisContext(this) })()'; const f = vm.runInNewContext(s, vm); f(); Before this commit, it returned the |this| of the new context, now it returns the |this| of the enclosing context. Two steps forward, one step back. Fixes: nodejs#7788 Refs: nodejs#14757
Closing this because it has stalled. Feel free to reopen if this issue is still relevant, or to ping the collaborator who labelled it stalled if you have any questions. |
prints
suggesting that
vm.runInThisContext
always runs the code in the top context rather than the current context.The text was updated successfully, but these errors were encountered: