diff --git a/src/node_contextify.cc b/src/node_contextify.cc index 7ec03c10f7743a..95911be7e708e6 100644 --- a/src/node_contextify.cc +++ b/src/node_contextify.cc @@ -380,7 +380,19 @@ class ContextifyContext { if (ctx->context_.IsEmpty()) return; - ctx->sandbox()->Set(property, value); + bool is_declared = + ctx->global_proxy()->HasRealNamedProperty(ctx->context(), + property).FromJust(); + bool is_contextual_store = ctx->global_proxy() != args.This(); + + bool set_property_will_throw = + args.ShouldThrowOnError() && + !is_declared && + is_contextual_store; + + if (!set_property_will_throw) { + ctx->sandbox()->Set(property, value); + } } diff --git a/test/parallel/test-vm-strict-mode.js b/test/parallel/test-vm-strict-mode.js new file mode 100644 index 00000000000000..f3820d8aead6af --- /dev/null +++ b/test/parallel/test-vm-strict-mode.js @@ -0,0 +1,27 @@ +'use strict'; +require('../common'); +const assert = require('assert'); +const vm = require('vm'); +const ctx = vm.createContext(); + +// Test strict mode inside a vm script, i.e., using an undefined variable +// throws a ReferenceError. Also check that variables +// that are not successfully set in the vm, must not be set +// on the sandboxed context. + +vm.runInContext('w = 1;', ctx); +assert.strictEqual(1, ctx.w); + +assert.throws(function() { vm.runInContext('"use strict"; x = 1;', ctx); }, + /ReferenceError: x is not defined/); +assert.strictEqual(undefined, ctx.x); + +vm.runInContext('"use strict"; var y = 1;', ctx); +assert.strictEqual(1, ctx.y); + +vm.runInContext('"use strict"; this.z = 1;', ctx); +assert.strictEqual(1, ctx.z); + +// w has been defined +vm.runInContext('"use strict"; w = 2;', ctx); +assert.strictEqual(2, ctx.w);