diff --git a/src/node.cc b/src/node.cc index cedcc64d74..78b0def92e 100644 --- a/src/node.cc +++ b/src/node.cc @@ -862,6 +862,9 @@ Handle EvalCX(const Arguments& args) { // Create the new context Persistent context = Context::New(); + // Enter and compile script + context->Enter(); + // Copy objects from global context, to our brand new context Handle keys = sandbox->GetPropertyNames(); @@ -869,12 +872,13 @@ Handle EvalCX(const Arguments& args) { for (i = 0; i < keys->Length(); i++) { Handle key = keys->Get(Integer::New(i))->ToString(); Handle value = sandbox->Get(key); - context->Global()->Set(key, value->ToObject()->Clone()); + if (value->IsFunction()) continue; + if (value->IsObject()) { + value = value->ToObject()->Clone(); + } + context->Global()->Set(key, value); } - // Enter and compile script - context->Enter(); - // Catch errors TryCatch try_catch; @@ -887,6 +891,18 @@ Handle EvalCX(const Arguments& args) { result = script->Run(); if (result.IsEmpty()) { result = ThrowException(try_catch.Exception()); + } else { + // success! copy changes back onto the sandbox object. + keys = context->Global()->GetPropertyNames(); + for (i = 0; i < keys->Length(); i++) { + Handle key = keys->Get(Integer::New(i))->ToString(); + Handle value = context->Global()->Get(key); + if (value->IsFunction()) continue; + if (value->IsObject()) { + value = value->ToObject()->Clone(); + } + sandbox->Set(key, value); + } } } diff --git a/test/simple/test-eval-cx.js b/test/simple/test-eval-cx.js index 32d5c94436..49b8ca10a0 100644 --- a/test/simple/test-eval-cx.js +++ b/test/simple/test-eval-cx.js @@ -14,14 +14,19 @@ process.evalcx('hello = 2'); assert.equal(5, hello); -code = "foo = 1; bar = 2;"; -foo = 2; -obj = { foo : 0 }; -process.evalcx(code, obj); +code = "foo = 1;" + + "bar = 2;" + + "if (baz !== 3) throw new Error('test fail');" + + "quux.pwned = true;"; -/* TODO? +foo = 2; +var quux = { pwned : false }; +obj = { foo : 0, baz : 3, quux : quux }; +var baz = process.evalcx(code, obj); assert.equal(1, obj.foo); assert.equal(2, obj.bar); -*/ +assert.equal(obj.quux.pwned, true); +assert.equal(quux.pwned, false); +assert.notEqual(quux, obj.quux); assert.equal(2, foo);