diff options
author | Franziska Hinkelmann <franziska.hinkelmann@gmail.com> | 2017-10-25 13:49:58 +0200 |
---|---|---|
committer | Franziska Hinkelmann <franziska.hinkelmann@gmail.com> | 2017-10-27 10:12:02 +0200 |
commit | 5856c836eaa2738269470e16b7ac7c1a92eac6d0 (patch) | |
tree | a117a03215dab708cb399d0bc9cd49e0fb509b57 | |
parent | fa939f0cf59fdafae6748b390bcfc733f188b425 (diff) | |
download | android-node-v8-5856c836eaa2738269470e16b7ac7c1a92eac6d0.tar.gz android-node-v8-5856c836eaa2738269470e16b7ac7c1a92eac6d0.tar.bz2 android-node-v8-5856c836eaa2738269470e16b7ac7c1a92eac6d0.zip |
src: fix vm module for strict mode
This patch fixes the problem with variables that
are declared only on the sandbox but not on the
global proxy.
PR-URL: https://github.com/nodejs/node/pull/16487
Fixes: https://github.com/nodejs/node/issues/12300
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Michaƫl Zasso <targos@protonmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
-rw-r--r-- | src/node_contextify.cc | 21 | ||||
-rw-r--r-- | test/parallel/test-vm-strict-mode.js (renamed from test/known_issues/test-vm-strict-mode.js) | 7 |
2 files changed, 21 insertions, 7 deletions
diff --git a/src/node_contextify.cc b/src/node_contextify.cc index fbc04ba0c0..12edf20810 100644 --- a/src/node_contextify.cc +++ b/src/node_contextify.cc @@ -346,14 +346,21 @@ class ContextifyContext { return; auto attributes = PropertyAttribute::None; - bool is_declared = ctx->global_proxy() + bool is_declared_on_global_proxy = ctx->global_proxy() ->GetRealNamedPropertyAttributes(ctx->context(), property) .To(&attributes); bool read_only = static_cast<int>(attributes) & static_cast<int>(PropertyAttribute::ReadOnly); - if (is_declared && read_only) + bool is_declared_on_sandbox = ctx->sandbox() + ->GetRealNamedPropertyAttributes(ctx->context(), property) + .To(&attributes); + read_only = read_only || + (static_cast<int>(attributes) & + static_cast<int>(PropertyAttribute::ReadOnly)); + + if (read_only) return; // true for x = 5 @@ -371,10 +378,20 @@ class ContextifyContext { // this.f = function() {}, is_contextual_store = false. bool is_function = value->IsFunction(); + bool is_declared = is_declared_on_global_proxy || is_declared_on_sandbox; if (!is_declared && args.ShouldThrowOnError() && is_contextual_store && !is_function) return; + if (!is_declared_on_global_proxy && is_declared_on_sandbox && + args.ShouldThrowOnError() && is_contextual_store && !is_function) { + // The property exists on the sandbox but not on the global + // proxy. Setting it would throw because we are in strict mode. + // Don't attempt to set it by signaling that the call was + // intercepted. Only change the value on the sandbox. + args.GetReturnValue().Set(false); + } + ctx->sandbox()->Set(property, value); } diff --git a/test/known_issues/test-vm-strict-mode.js b/test/parallel/test-vm-strict-mode.js index 9528944732..b1b233664d 100644 --- a/test/known_issues/test-vm-strict-mode.js +++ b/test/parallel/test-vm-strict-mode.js @@ -7,11 +7,8 @@ const vm = require('vm'); const ctx = vm.createContext({ x: 42 }); -// The following line wrongly throws an -// error because GlobalPropertySetterCallback() -// does not check if the property exists -// on the sandbox. It should just set x to 1 -// instead of throwing an error. +// This might look as if x has not been declared, but x is defined on the +// sandbox and the assignment should not throw. vm.runInContext('"use strict"; x = 1', ctx); assert.strictEqual(ctx.x, 1); |