diff --git a/src/node_contextify.cc b/src/node_contextify.cc index 2b08a33f5d5ee9..953af01084b65e 100644 --- a/src/node_contextify.cc +++ b/src/node_contextify.cc @@ -26,6 +26,9 @@ using v8::HandleScope; using v8::Integer; using v8::Isolate; using v8::Local; +using v8::MaybeLocal; +using v8::Name; +using v8::NamedPropertyHandlerConfiguration; using v8::None; using v8::Object; using v8::ObjectTemplate; @@ -202,12 +205,14 @@ class ContextifyContext { Local object_template = function_template->InstanceTemplate(); - object_template->SetNamedPropertyHandler(GlobalPropertyGetterCallback, + + NamedPropertyHandlerConfiguration config(GlobalPropertyGetterCallback, GlobalPropertySetterCallback, GlobalPropertyQueryCallback, GlobalPropertyDeleterCallback, GlobalPropertyEnumeratorCallback, CreateDataWrapper(env)); + object_template->SetHandler(config); Local ctx = Context::New(env->isolate(), nullptr, object_template); if (!ctx.IsEmpty()) @@ -342,7 +347,7 @@ class ContextifyContext { static void GlobalPropertyGetterCallback( - Local property, + Local property, const PropertyCallbackInfo& args) { Isolate* isolate = args.GetIsolate(); HandleScope scope(isolate); @@ -351,22 +356,27 @@ class ContextifyContext { Unwrap(args.Data().As()); Local sandbox = PersistentToLocal(isolate, ctx->sandbox_); - Local rv = sandbox->GetRealNamedProperty(property); + MaybeLocal rv = + sandbox->GetRealNamedProperty(ctx->context(), property); if (rv.IsEmpty()) { Local proxy_global = PersistentToLocal(isolate, ctx->proxy_global_); - rv = proxy_global->GetRealNamedProperty(property); - } - if (!rv.IsEmpty() && rv == ctx->sandbox_) { - rv = PersistentToLocal(isolate, ctx->proxy_global_); + rv = proxy_global->GetRealNamedProperty(ctx->context(), property); } - args.GetReturnValue().Set(rv); + Local localRV; + if (rv.ToLocal(&localRV)) { + if (localRV == ctx->sandbox_) { + rv = PersistentToLocal(isolate, ctx->proxy_global_); + } + + args.GetReturnValue().Set(localRV); + } } static void GlobalPropertySetterCallback( - Local property, + Local property, Local value, const PropertyCallbackInfo& args) { Isolate* isolate = args.GetIsolate(); @@ -380,7 +390,7 @@ class ContextifyContext { static void GlobalPropertyQueryCallback( - Local property, + Local property, const PropertyCallbackInfo& args) { Isolate* isolate = args.GetIsolate(); HandleScope scope(isolate); @@ -392,31 +402,43 @@ class ContextifyContext { Local proxy_global = PersistentToLocal(isolate, ctx->proxy_global_); - if (sandbox->HasRealNamedProperty(property)) { - PropertyAttribute propAttr = - sandbox->GetRealNamedPropertyAttributes(property).FromJust(); - args.GetReturnValue().Set(propAttr); - } else if (proxy_global->HasRealNamedProperty(property)) { + bool in_sandbox = + sandbox->HasRealNamedProperty(ctx->context(), property).FromMaybe(false); + + if (in_sandbox) { PropertyAttribute propAttr = - proxy_global->GetRealNamedPropertyAttributes(property).FromJust(); + sandbox-> + GetRealNamedPropertyAttributes(ctx->context(), property).FromJust(); args.GetReturnValue().Set(propAttr); } else { - args.GetReturnValue().Set(None); + bool in_proxy_global = + proxy_global->HasRealNamedProperty(ctx->context(), property) + .FromMaybe(false); + if (in_proxy_global) { + PropertyAttribute propAttr = + proxy_global-> + GetRealNamedPropertyAttributes(ctx->context(), property) + .FromJust(); + args.GetReturnValue().Set(propAttr); + } + else { + args.GetReturnValue().Set(None); + } } } static void GlobalPropertyDeleterCallback( - Local property, + Local property, const PropertyCallbackInfo& args) { Isolate* isolate = args.GetIsolate(); HandleScope scope(isolate); ContextifyContext* ctx = Unwrap(args.Data().As()); + Local sandbox = PersistentToLocal(isolate, ctx->sandbox_); - bool success = PersistentToLocal(isolate, - ctx->sandbox_)->Delete(property); + bool success = sandbox->Delete(ctx->context(), property).FromMaybe(false); args.GetReturnValue().Set(success); } diff --git a/test/parallel/test-vm-symbols.js b/test/parallel/test-vm-symbols.js new file mode 100644 index 00000000000000..ff4b0c7636ee96 --- /dev/null +++ b/test/parallel/test-vm-symbols.js @@ -0,0 +1,23 @@ +var common = require('../common'); +var assert = require('assert'); + +var vm = require('vm'); + +var symbol = Symbol(); + +function Document() { + this[symbol] = 'foo'; +} + +Document.prototype.getSymbolValue = function () { + return this[symbol]; +}; + +var context = new Document(); +vm.createContext(context); + +assert.equal(context.getSymbolValue(), 'foo', + 'should return symbol-keyed value from the outside'); + +assert.equal(vm.runInContext('this.getSymbolValue()', context), 'foo', + 'should return symbol-keyed value from the inside');