diff --git a/src/node_contextify.cc b/src/node_contextify.cc index 2b08a33f5d5ee9..57de89560b50b2 100644 --- a/src/node_contextify.cc +++ b/src/node_contextify.cc @@ -26,6 +26,10 @@ using v8::HandleScope; using v8::Integer; using v8::Isolate; using v8::Local; +using v8::Maybe; +using v8::MaybeLocal; +using v8::Name; +using v8::NamedPropertyHandlerConfiguration; using v8::None; using v8::Object; using v8::ObjectTemplate; @@ -202,12 +206,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 +348,7 @@ class ContextifyContext { static void GlobalPropertyGetterCallback( - Local property, + Local property, const PropertyCallbackInfo& args) { Isolate* isolate = args.GetIsolate(); HandleScope scope(isolate); @@ -351,22 +357,27 @@ class ContextifyContext { Unwrap(args.Data().As()); Local sandbox = PersistentToLocal(isolate, ctx->sandbox_); - Local rv = sandbox->GetRealNamedProperty(property); - if (rv.IsEmpty()) { + MaybeLocal maybeRV = + sandbox->GetRealNamedProperty(ctx->context(), property); + if (maybeRV.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_); + maybeRV = proxy_global->GetRealNamedProperty(ctx->context(), property); } - args.GetReturnValue().Set(rv); + Local rv; + if (maybeRV.ToLocal(&rv)) { + if (rv == ctx->sandbox_) { + rv = PersistentToLocal(isolate, ctx->proxy_global_); + } + + args.GetReturnValue().Set(rv); + } } static void GlobalPropertySetterCallback( - Local property, + Local property, Local value, const PropertyCallbackInfo& args) { Isolate* isolate = args.GetIsolate(); @@ -380,7 +391,7 @@ class ContextifyContext { static void GlobalPropertyQueryCallback( - Local property, + Local property, const PropertyCallbackInfo& args) { Isolate* isolate = args.GetIsolate(); HandleScope scope(isolate); @@ -389,35 +400,40 @@ class ContextifyContext { Unwrap(args.Data().As()); Local sandbox = PersistentToLocal(isolate, ctx->sandbox_); - 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)) { - PropertyAttribute propAttr = - proxy_global->GetRealNamedPropertyAttributes(property).FromJust(); + Maybe maybePropAttr = + sandbox->GetRealNamedPropertyAttributes(ctx->context(), property); + + if (maybePropAttr.IsNothing()) { + Local proxy_global = PersistentToLocal(isolate, + ctx->proxy_global_); + + maybePropAttr = + proxy_global->GetRealNamedPropertyAttributes(ctx->context(), property); + } + + if (maybePropAttr.IsJust()) { + PropertyAttribute propAttr = maybePropAttr.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_); + + Maybe success = sandbox->Delete(ctx->context(), property); - bool success = PersistentToLocal(isolate, - ctx->sandbox_)->Delete(property); - args.GetReturnValue().Set(success); + if (success.IsJust()) { + args.GetReturnValue().Set(success.FromJust()); + } } 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');