-
Notifications
You must be signed in to change notification settings - Fork 29.6k
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
Function redefinition in vm.runInContext #548
Comments
Confirmed result difference, 0 in iojs and 1 in node (all current versions (0.10.33 & 0.11.15) |
It seems that a |
What version of node? Likely this is due to the switch to contextify internally. |
This does seem bad, as the intention here is similar to <script>
function test() { return 0; }
</script>
<script>
function test() { return 1; }
</script>
<script>
alert(test());
</script> (which alerts 1). I wonder if it is due to 3c5ea41 |
@domenic not directly / not alone, that commit exists in 0.11.15, which also appears to have the bug. |
@Fishrock123 right, I am wondering what the behavior was before that commit but after the contextify switch. |
Possibly related: nodejs/node-v0.x-archive#9084 |
Still returning 0 on v2.1.0. |
@domenic is this fixed in next? |
Haven't been able to test this with the new patches, but I didn't see any reason why the new patches would necessarily fix it. I still have a list of vm bugs to work on :) |
Behavior still occurs in 3.0, marking as a bug! |
Still returns 0 in v4.2.0. |
I think I understand the problem here (but I don't know how to fix it):
You don't need to redefine a function to see the problem. Just put a property with the same name in the context before running the code: > var vm = require('vm'), ctx = vm.createContext({});
> vm.runInContext('function a(){return 0}', ctx);
> ctx
{ a: [Function: a] }
> var vm = require('vm'), ctx = vm.createContext({a: 1});
> vm.runInContext('function a(){return 0}', ctx);
> ctx
{ a: 1 } |
Wait, I have an idea for a fix |
So I can't make it work, probably because I don't really understand V8's API. Here is the patch I tried: Index: src/node_contextify.cc
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- src/node_contextify.cc (revision 6f14b3a7db93d3d2e2c20b3489dd7ddb7171ee97)
+++ src/node_contextify.cc (revision )
@@ -138,8 +138,8 @@
int length = names->Length();
for (int i = 0; i < length; i++) {
Local<String> key = names->Get(i)->ToString(env()->isolate());
- bool has = sandbox->HasOwnProperty(key);
- if (!has) {
+ bool isEqual = sandbox->Get(key)->SameValue(global->Get(key));
+ if (!isEqual) {
// Could also do this like so:
//
// PropertyAttribute att = global->GetPropertyAttributes(key_v); For some reason, as soon as the property exists on both sides, cc @bnoordhuis ? |
I have not confirmed but my guess as to what's wrong with your patch is that by using ->Get, you are triggering the interceptors which contextify installs. You might want to try replacing one or both of those with GetRealNamedPropertyInPrototypeChain or GetRealNamedProperty. However, I think the ultimate fix here (for this and other issues) might be to try to copy the Blink architecture a bit better. See https://groups.google.com/forum/#!topic/v8-users/OwcOrXYOpUE which was originally about #2734 but might have broader correctness implications. |
The issue seems to be that GlobalPropertySetterCallback isn't even called when defining a function with the form "function a() {}", but everything works as expected when running "a = function () {}". Test case: 'use strict';
var common = require('../common');
var assert = require('assert');
var vm = require('vm');
var ctx = vm.createContext({a: 1});
// Uncomment the following line to make test pass
//vm.runInContext('a = function () {}', ctx);
vm.runInContext('function a() {}', ctx);
assert.equal(typeof ctx.a, 'function'); |
This commit adds a failing test case for the vm module. Currently, if runInContext() defines a function, and a later call to runInContext() redefines the same function, the original function is not overwritten. Refs: nodejs#548
This commit adds a failing test case for the vm module. Currently, if runInContext() defines a function, and a later call to runInContext() redefines the same function, the original function is not overwritten. Refs: #548 PR-URL: #5528 Reviewed-By: James M Snell <[email protected]> Reviewed-By: Wyatt Preul <[email protected]> Reviewed-By: Rich Trott <[email protected]>
Possible bug of iojs or perhaps v8?
Tested under win7 x64 and linux.
The text was updated successfully, but these errors were encountered: