src: don't overwrite non-writable vm globals
Check that the property doesn't have the read-only flag set before overwriting it. Fixes: https://github.com/nodejs/node/issues/10223 PR-URL: https://github.com/nodejs/node/pull/10227 Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com> Reviewed-By: Franziska Hinkelmann <franziska.hinkelmann@gmail.com>
This commit is contained in:
parent
3b2a630653
commit
524f693872
@ -383,19 +383,22 @@ class ContextifyContext {
|
|||||||
if (ctx->context_.IsEmpty())
|
if (ctx->context_.IsEmpty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
auto attributes = PropertyAttribute::None;
|
||||||
bool is_declared =
|
bool is_declared =
|
||||||
ctx->global_proxy()->HasRealNamedProperty(ctx->context(),
|
ctx->global_proxy()->GetRealNamedPropertyAttributes(ctx->context(),
|
||||||
property).FromJust();
|
property)
|
||||||
bool is_contextual_store = ctx->global_proxy() != args.This();
|
.To(&attributes);
|
||||||
|
bool read_only =
|
||||||
|
static_cast<int>(attributes) &
|
||||||
|
static_cast<int>(PropertyAttribute::ReadOnly);
|
||||||
|
|
||||||
bool set_property_will_throw =
|
if (is_declared && read_only)
|
||||||
args.ShouldThrowOnError() &&
|
return;
|
||||||
!is_declared &&
|
|
||||||
is_contextual_store;
|
|
||||||
|
|
||||||
if (!set_property_will_throw) {
|
if (!is_declared && args.ShouldThrowOnError())
|
||||||
ctx->sandbox()->Set(property, value);
|
return;
|
||||||
}
|
|
||||||
|
ctx->sandbox()->Set(property, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -75,3 +75,14 @@ assert.throws(function() {
|
|||||||
// https://github.com/nodejs/node/issues/6158
|
// https://github.com/nodejs/node/issues/6158
|
||||||
ctx = new Proxy({}, {});
|
ctx = new Proxy({}, {});
|
||||||
assert.strictEqual(typeof vm.runInNewContext('String', ctx), 'function');
|
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, undefined); // Not copied out by cloneProperty().
|
||||||
|
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);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user