Skip to content

Commit d8a5e1c

Browse files
fhinkelitaloacasas
authored andcommittedFeb 14, 2017
src: don't overwrite non-writable vm globals
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 PR-URL: #11109 Reviewed-By: Ben Noordhuis <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: Sakthipriyan Vairamani <[email protected]>
1 parent 5649174 commit d8a5e1c

File tree

2 files changed

+31
-9
lines changed

2 files changed

+31
-9
lines changed
 

‎src/node_contextify.cc

+18-9
Original file line numberDiff line numberDiff line change
@@ -383,19 +383,28 @@ class ContextifyContext {
383383
if (ctx->context_.IsEmpty())
384384
return;
385385

386+
auto attributes = PropertyAttribute::None;
386387
bool is_declared =
387-
ctx->global_proxy()->HasRealNamedProperty(ctx->context(),
388-
property).FromJust();
388+
ctx->global_proxy()->GetRealNamedPropertyAttributes(ctx->context(),
389+
property)
390+
.To(&attributes);
391+
bool read_only =
392+
static_cast<int>(attributes) &
393+
static_cast<int>(PropertyAttribute::ReadOnly);
394+
395+
if (is_declared && read_only)
396+
return;
397+
398+
// true for x = 5
399+
// false for this.x = 5
400+
// false for Object.defineProperty(this, 'foo', ...)
401+
// false for vmResult.x = 5 where vmResult = vm.runInContext();
389402
bool is_contextual_store = ctx->global_proxy() != args.This();
390403

391-
bool set_property_will_throw =
392-
args.ShouldThrowOnError() &&
393-
!is_declared &&
394-
is_contextual_store;
404+
if (!is_declared && args.ShouldThrowOnError() && is_contextual_store)
405+
return;
395406

396-
if (!set_property_will_throw) {
397-
ctx->sandbox()->Set(property, value);
398-
}
407+
ctx->sandbox()->Set(property, value);
399408
}
400409

401410

‎test/parallel/test-vm-context.js

+13
Original file line numberDiff line numberDiff line change
@@ -75,3 +75,16 @@ assert.throws(function() {
7575
// https://github.com/nodejs/node/issues/6158
7676
ctx = new Proxy({}, {});
7777
assert.strictEqual(typeof vm.runInNewContext('String', ctx), 'function');
78+
79+
// https://github.com/nodejs/node/issues/10223
80+
ctx = vm.createContext();
81+
vm.runInContext('Object.defineProperty(this, "x", { value: 42 })', ctx);
82+
assert.strictEqual(ctx.x, 42);
83+
assert.strictEqual(vm.runInContext('x', ctx), 42);
84+
85+
vm.runInContext('x = 0', ctx); // Does not throw but x...
86+
assert.strictEqual(vm.runInContext('x', ctx), 42); // ...should be unaltered.
87+
88+
assert.throws(() => vm.runInContext('"use strict"; x = 0', ctx),
89+
/Cannot assign to read only property 'x'/);
90+
assert.strictEqual(vm.runInContext('x', ctx), 42);

0 commit comments

Comments
 (0)
Please sign in to comment.