开发者

Node JavaScript contexts sharing built-in prototypes?

When creating a new context with Node's vm.runInNewContext, are built-in (Object, Function, etc.) prototypes shared or not?

Documentation on runInNewContext says:

Running code does not have access to local scope and the object sandbox will be used as the global object for code.

Is Object.prototype in the global scope, hence not shared?

In node_script.cc:338-345 and node_script.cc:403-409 I see it's referencing the objects, so are those objects, from sandbox, using the Object.prototype of the parent context which calls vm.runInNewContext and objects created in the new context using a different Object.prototype?

(Note: vm module is a maze: vm module -开发者_如何学Python> evals process.binding -> node_script.cc source)


As far as I know the code is run in a completely new context, with different global constructors for Object, Array, etc.

Object.prototype.a = function() { console.log('hello'); };
({}).a(); // 'hello'
require('vm').runInNewContext('({}).a();'); // should throw

I don't think it would really be a new context if Object::a had access to variables in the original context.

This has some implications though:

vm.runInNewContext('[];') instanceof Array; // returns false

Because that array was created with a completely different constructor, the instanceof operator will be affected.


Conclusion

Inside a vm.runInNewContext, there are two Object.prototypes: one that is created inside the new context and one that is referencing to the parent context, via the sandbox. Apparently, Node has set the security tokens correctly, so contexts are allowed to access the parent's objects.

Is Object.prototype in the global scope, hence not shared?

It is not in the global scope, but in the context. It's not shared.

In node_script.cc:338-345 and node_script.cc:403-409 I see it's referencing the objects, so are those objects, from sandbox, using the Object.prototype of the parent context which calls vm.runInNewContext and objects created in the new context using a different Object.prototype?

Yes.

When creating a new context with Node's vm.runInNewContext, are built-in (Object, Function, etc.) prototypes shared or not?

Not shared.

The test

// Test

var vm = require('vm');

var parentLog = function(message) {
    process.stdout.write(message + "\n");
}

Object.prototype.test = "[parent Object.prototype.test]";

var parentObject = new String("[parent parentObject]");

var parentSandbox = {
    log: parentLog,
    testObject: parentObject,
};

var parentCode =
    "log('vm testObject: ' + testObject);" +
    "log('vm testObject.test: ' + testObject.test);" +
    "log('vm create Object.prototype.test');" +
    "Object.prototype.test = '[vm Object.prototype.test]';" +
    "log('vm Object.prototype.test: ' + Object.prototype.test);" +
    "log('vm testObject.test: ' + testObject.test);";

parentLog('pre-parent parentObject: ' + parentObject);
parentLog('pre-parent parentObject.test: ' + parentObject.test);
parentLog('pre-parent Object.prototype: ' + Object.prototype.test);

var parentScript = vm.createScript(parentCode, "<test>");
parentScript.runInNewContext(parentSandbox);

parentLog('post-parent parentObject: ' + parentObject);
parentLog('post-parent parentObject.test: ' + parentObject.test);
parentLog('post-parent Object.prototype: ' + Object.prototype.test);

Output:

pre-parent parentObject: [parent parentObject]
pre-parent parentObject.test: [parent Object.prototype.test]
pre-parent Object.prototype: [parent Object.prototype.test]
vm testObject: [parent parentObject]
vm testObject.test: [parent Object.prototype.test]
vm create Object.prototype.test
vm Object.prototype.test: [vm Object.prototype.test]
vm testObject.test: [parent Object.prototype.test]
post-parent parentObject: [parent parentObject]
post-parent parentObject.test: [parent Object.prototype.test]
post-parent Object.prototype: [parent Object.prototype.test]
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜