Skip to content
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

Global object, this and indirect eval call in vm sandbox #3593

Closed
eush77 opened this issue Oct 29, 2015 · 2 comments
Closed

Global object, this and indirect eval call in vm sandbox #3593

eush77 opened this issue Oct 29, 2015 · 2 comments
Labels
vm Issues and PRs related to the vm subsystem.

Comments

@eush77
Copy link

eush77 commented Oct 29, 2015

I have a couple of questions regarding the behavior of this and (1, eval)("this") in vm.

According to 18.2.1.1 and 8.1.1.4.11 of ECMAScript language specification, this and (1, eval)("this") in the global scope both resolve to the global object, and according to vm module docs, the global object is the sandbox argument to vm.runInNewContext for scripts running this way:

Inside scripts run as such, sandbox will be the global object, retaining all its existing properties but also having the built-in objects and functions any standard global object has.

Is my understanding correct? I don't really understand these results I got:

var vm = require('vm');
var sandbox = vm.createContext();

console.log(sandbox === vm.runInNewContext('this', sandbox)) //=> false (1)
console.log(sandbox === vm.runInNewContext('(1, eval)("this")', sandbox)) //=> false (2)

console.log(vm.runInNewContext('this === (1, eval)("this")', {})) //=> true (3)
console.log(vm.runInNewContext('this === (1, eval)("this")', global)) //=> false (4)
console.log(vm.runInNewContext('this === (1, eval)("this")',
                               Object.create(global))) //=> false (5)

console.log(prototypeChain(Object.create(null)).length) //=> 1 (6)
console.log(prototypeChain(vm.runInNewContext('this',
                                              Object.create(null))).length) //=> 3 (7)

function prototypeChain (object) {
  var chain = [];
  while (object) {
    chain.push(object);
    object = Object.getPrototypeOf(object);
  }
  return chain;
}
  1. Why false in (1) and (2)? I know that e.g. mutating or adding properties to this inside vm is visible outside, is there a technical reason for these objects not being equal and also for the difference between (6) and (7)?
  2. Why is the value of this === (1, eval)("this") not consistent and why does it depend on the presence of global in the sandbox's prototype chain? Is global unique in this regard?
$ node --version
v4.1.0
@mscdex mscdex added the vm Issues and PRs related to the vm subsystem. label Oct 30, 2015
@bnoordhuis
Copy link
Member

Why false in (1) and (2)?

The context doesn't interact with the sandbox object directly, there is a proxy object in between.

Why is the value of this === (1, eval)("this") not consistent and why does it depend on the presence of global in the sandbox's prototype chain?

Because of this:

> global.eval === vm.runInNewContext('(1,eval)', {})
false
> global.eval === vm.runInNewContext('(1,eval)', global)
true

When you pass global as the sandbox, you end up calling the eval function from the outer context.

@eush77
Copy link
Author

eush77 commented Oct 30, 2015

@bnoordhuis Thank you! This makes sense now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
vm Issues and PRs related to the vm subsystem.
Projects
None yet
Development

No branches or pull requests

3 participants