Skip to content
This repository has been archived by the owner on Apr 22, 2023. It is now read-only.

vm.runInContext calls to external functions, can't access the context passed to them. #1461

Closed
shimondoodkin opened this issue Aug 6, 2011 · 7 comments
Labels

Comments

@shimondoodkin
Copy link

it looks like a bug. maybe in v8.
maybe something related to locks or to checking the context

pinpointed:

var vm = require('vm');
var sandbox = {
  go: function(parentglobal) {
   // 2. print the same global outside
    var s="s6:";  for(var aneach in parentglobal) s+=","+aneach;  console.log(s);
  },
  console:console
};

vm.runInNewContext(
'var global=this;' +
'('+ function() {

global.foo = 1;
global.bar = 2;

//1. print the global inside
var s="s5:";  for(var aneach in global) s+=","+aneach;  console.log(s);

go(global); // from the inside ask an outside function to print global  

}+ ')()', sandbox);
/*
output:
s5:,console,go,global,foo,bar
s6:
// s6 should be like s5
*/

full thing,
displays global in each step:

var vm = require('vm') , context, sandbox;
sandbox = {
setTimeout: setTimeout,
console: console,

go1: function(parentsglobal) {
var s="//s6:"; for(var aneach in parentsglobal) s+=","+aneach; console.log(s);
var s="//s7:"; for(var aneach in this) s+=","+aneach; console.log(s);
var s="//s8:"; for(var aneach in sandbox) s+=","+aneach; console.log(s);
var s="//s9:"; for(var aneach in context) s+=","+aneach;  console.log(s);
} ,

go: function(parentsglobal) {
var s="s6:"; for(var aneach in parentsglobal) s+=","+aneach; console.log(s);
var s="s7:"; for(var aneach in this) s+=","+aneach; console.log(s);
var s="s8:"; for(var aneach in sandbox) s+=","+aneach; console.log(s);
var s="s9:"; for(var aneach in context) s+=","+aneach;  console.log(s);
}


};
context= vm.createContext( sandbox );

var z=vm.runInContext(
'"use strict";' +
//'this.__defineGetter__(\'global\',function(){return this;});' +
'var global=this;' +
'var s="s1:"; '+
'for(var aneach in this) s+=","+aneach; '+
'console.log(s);' +
'(' +

function() {

 var s="s2:";
 for(var aneach in this) s+=","+aneach;
 console.log(s);

 var s="s3:";
 for(var aneach in global) s+=","+aneach;
 console.log(s);


 global.foo = 1;
 setTimeout(function () {
 global.bar = 2;

 var s="s4:";
 for(var aneach in this) s+=","+aneach;
 console.log(s);

 var s="s5:";
 for(var aneach in global) s+=","+aneach;
 console.log(s);

 go(global);

}, 100);
// go1(global);

}
+ ')()'
, context);

/*
output:
s1:,setTimeout,console,go1,go,global,s,aneach
s2:,setTimeout,console,go1,go,global,s,aneach
s3:,setTimeout,console,go1,go,global,s,aneach
s4:,_idleTimeout,_onTimeout,_idlePrev,_idleNext,_idleStart
s5:,setTimeout,console,go1,go,global,s,aneach,foo,bar
s6:
s7:
s8:,setTimeout,console,go1,go
s9:,setTimeout,console,go1,go,global,s,aneach,foo
// s6 should be like s5

*/
@rehanift
Copy link

I am running into this issue too. Here are my steps to reproduce. It appears that references to the global scope cannot be passed down to functions (test 2, test 4), though local variables can (test 1, test 3). Is this by design?

My use case here is that I would like to be able to pass an anonymous function as a parameter (ie. a callback for "somefunc"). The passed callback should have access to the global scope.

var vm = require("vm");

var sandbox;
var makeSandbox = function(){
    return {
    somefunc: function(somevar){
        somevar.foo = "bar";
    }
    };
};

sandbox = makeSandbox();
vm.runInNewContext("var test1 = {}; somefunc(test1);", sandbox);
console.log("test 1",sandbox);
// test 1 { somefunc: [Function], test1: { foo: 'bar' } }

sandbox = makeSandbox();
vm.runInNewContext("var test2 = this; somefunc(test2);", sandbox);
console.log("test 2",sandbox);
// test 2 { somefunc: [Function], test2: [Circular] }

sandbox = makeSandbox();
sandbox.somevar = {};
vm.runInNewContext("var test3 = somevar; somefunc(test3);", sandbox);
console.log("test 3",sandbox);
// test 3 { somefunc: [Function], somevar: { foo: 'bar' }, test3: { foo: 'bar' } }

sandbox = makeSandbox();
sandbox.somevar = sandbox;
vm.runInNewContext("var test4 = somevar; somefunc(test4);", sandbox);
console.log("test 4",sandbox);
// test 4 { somefunc: [Function], somevar: [Circular], test4: [Circular] }

@ELLIOTTCABLE
Copy link

As documented in #1801, I believe I’ve closed this with elliottcable@cf21650. I’d appreciate if you’d clone and compile against that, and see if you can still reproduce this issue. (Many of these issues seem related.)

@bnoordhuis
Copy link
Member

I'm not sure I understand what the issue is about. The test from @rehanift prints the following with master:

test 1 { somefunc: [Function], test1: { foo: 'bar' } }
test 2 { somefunc: [Function], test2: {} }
test 3 { somefunc: [Function], somevar: { foo: 'bar' }, test3: { foo: 'bar' } }
test 4 { somefunc: [Function], somevar: [Circular], test4: [Circular], foo: 'bar' }

Looks okay to me. Am I missing something?

@trevnorris
Copy link

@bnoordhuis as discussed in #1389, this seems to be the expected functionality for runInNewContext. Take the following example:

sandbox = makeSandbox();
vm.runInNewContext('somefunc(this)', sandbox);
console.log(sandbox);
// { somefunc: [Function] }

Since runInNewContext creates a new temporary scope, then scraps it when the script is done, one shouldn't expect to be able affect the global scope from an anonymous function (as @rehanift has requested). If anyone thinks this shouldn't be the case then that feature request should be opened.

@whiskers75
Copy link

It's not a bug, it's a feature!

@alonbardavid
Copy link

Shouldn't this be closed?

@indutny
Copy link
Member

indutny commented Sep 2, 2014

Yeah, I think so.

@indutny indutny closed this as completed Sep 2, 2014
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

8 participants