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

setTimeout and/or context issue (runInContext) #1770

Closed
Ayms opened this issue Sep 26, 2011 · 2 comments
Closed

setTimeout and/or context issue (runInContext) #1770

Ayms opened this issue Sep 26, 2011 · 2 comments

Comments

@Ayms
Copy link

Ayms commented Sep 26, 2011

See the test case below, setTimeout does not accept strings in node.js (issue #550 closed), so when it is called with a string we pass to setTimeout new Function(string).

But doing this using runInContext causes setTimeout to execute in the global context.

There is a (kind of) workaround (see setTimeout2 below), but I am reporting this because this does not seem normal.

Test case :

var vm = require('vm');

test2='test2';

var f=function() {
this.test="test";
};

g=new f(); //global

g=vm.createContext(g);

g.g=g; //assign in g context global var g referring to it

g.console=console;

g.setTimeout=function(a,b) {if (typeof(a)=='string') {setTimeout(new Function(a),b)} else {setTimeout(a,b)}};

g.setTimeout2=function(a,b) {
    if (typeof(a)=='string') {
        var fn=function() {return vm.createScript(a, '').runInContext(g)};
        return setTimeout(fn,b);
    } else {
        setTimeout(a,b);
    }
};

var code='setTimeout("console.log(test)",2000)';

var code2='setTimeout2("console.log(test)",2000)';

vm.createScript(code, '').runInContext(g); //NOK test is undefined

vm.createScript(code2, '').runInContext(g); //OK display 'test'

var code='setTimeout("console.log(test2)",2000)';

vm.createScript(code, '').runInContext(g); // display 'test2' --> setTimeout does execute in global context

var code='var fn=function() {console.log(test)};setTimeout(fn,2000)';

vm.createScript(code, '').runInContext(g); //OK 'test'
@bnoordhuis
Copy link
Member

That's not really a bug. g.setTimeout is a function that's rooted in the main context. Thus, any function it creates is also rooted in said main context. The snippet below ties it to your custom context.

g.setTimeout = setTimeout;

vm.runInContext('                                       \
  setTimeout = (function(setTimeout_) {                 \
    return function(cb, timeout) {                      \
      if (typeof cb !== "function") cb = Function(cb);  \
      return setTimeout_(cb, timeout);                  \
    };                                                  \
  })(setTimeout)', g);

@Ayms
Copy link
Author

Ayms commented Sep 26, 2011

OK thanks, did you see #1674 ?

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

2 participants