Skip to content

Commit

Permalink
src: don't overwrite non-writable vm globals
Browse files Browse the repository at this point in the history
Check that the property doesn't have the read-only flag set before
overwriting it.

This is Ben Noordhuis previous commit, but keeping
is_contextual_store. is_contextual_store describes whether this.foo = 42 or
foo = 42 was called. The second is contextual and will fail
in strict mode if foo is used without declaration. Therefore only do an
early return if it is a contextual store. In particular,
don't do an early return for Object.defineProperty(this, ...).

Fixes: #10223
Refs: #10227
  • Loading branch information
fhinkel committed Feb 3, 2017
1 parent 1b30df1 commit c081b5b
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 9 deletions.
27 changes: 18 additions & 9 deletions src/node_contextify.cc
Original file line number Diff line number Diff line change
Expand Up @@ -383,19 +383,28 @@ class ContextifyContext {
if (ctx->context_.IsEmpty())
return;

auto attributes = PropertyAttribute::None;
bool is_declared =
ctx->global_proxy()->HasRealNamedProperty(ctx->context(),
property).FromJust();
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)
return;

// true for x = 5
// false for this.x = 5
// false for Object.defineProperty(this, 'foo', ...)
// false for vmResult.x = 5 where vmResult = vm.runInContext();
bool is_contextual_store = ctx->global_proxy() != args.This();

bool set_property_will_throw =
args.ShouldThrowOnError() &&
!is_declared &&
is_contextual_store;
if (!is_declared && args.ShouldThrowOnError() && is_contextual_store)
return;

if (!set_property_will_throw) {
ctx->sandbox()->Set(property, value);
}
ctx->sandbox()->Set(property, value);
}


Expand Down
13 changes: 13 additions & 0 deletions test/parallel/test-vm-context.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,3 +75,16 @@ assert.throws(function() {
// https://github.com/nodejs/node/issues/6158
ctx = new Proxy({}, {});
assert.strictEqual(typeof vm.runInNewContext('String', ctx), 'function');

// https://github.com/nodejs/node/issues/10223
ctx = vm.createContext();
vm.runInContext('Object.defineProperty(this, "x", { value: 42 })', ctx);
assert.strictEqual(ctx.x, 42);
assert.strictEqual(vm.runInContext('x', ctx), 42);

vm.runInContext('x = 0', ctx); // Does not throw but x...
assert.strictEqual(vm.runInContext('x', ctx), 42); // ...should be unaltered.

assert.throws(() => vm.runInContext('"use strict"; x = 0', ctx),
/Cannot assign to read only property 'x'/);
assert.strictEqual(vm.runInContext('x', ctx), 42);

0 comments on commit c081b5b

Please sign in to comment.