-
Notifications
You must be signed in to change notification settings - Fork 29.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
src: don't overwrite non-writable vm globals #11109
Conversation
7546f71
to
aa952c4
Compare
|
||
// https://github.com/nodejs/node/issues/10223 | ||
ctx = vm.createContext(); | ||
vm.runInContext('Object.defineProperty(this, "x", { value: 42 })', ctx); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: These tests can be logically grouped. Can you group them in blocks?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Which groups did you have in mind?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe something like this?
{
// https://github.com/nodejs/node/issues/10223
const 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);
}
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Blocks in JS Code look weird to me. I added some extra blank lines. OK like this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cool :-) This looks clean to my eyes now.
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: nodejs#10223 Refs: nodejs#10227
|
||
// https://github.com/nodejs/node/issues/10223 | ||
ctx = vm.createContext(); | ||
vm.runInContext('Object.defineProperty(this, "x", { value: 42 })', ctx); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cool :-) This looks clean to my eyes now.
Thanks for the reviews. Landed in e116cbe. |
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 <info@bnoordhuis.nl> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Sakthipriyan Vairamani <thechargingvolcano@gmail.com>
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: nodejs#10223 Refs: nodejs#10227 PR-URL: nodejs#11109 Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Sakthipriyan Vairamani <thechargingvolcano@gmail.com>
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: nodejs#10223 Refs: nodejs#10227 PR-URL: nodejs#11109 Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Sakthipriyan Vairamani <thechargingvolcano@gmail.com>
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: nodejs#10223 Refs: nodejs#10227 PR-URL: nodejs#11109 Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Sakthipriyan Vairamani <thechargingvolcano@gmail.com>
This would need a backport PR in order to land on v4 or v6 (if it should land on those at all) |
Another try for #10223.
This is @bnoordhuis reverted commit, without removing
is_contextual_store
.Now
defineProperty(this, ..., {value: })
is intercepted and copied by the SetterCallback and global assignment succeeds the first time. The callback does not overwrite read-only values.The first assert in the test is different from the reverted commit, because
defineProperty(..., {value: })
is intercepted and copied by the SetterCallback.https://github.com/nodejs/node/blob/master/test/known_issues/test-vm-data-property-writable.js is still a known issue, because the property descriptor is taken from the sandbox not the vm context. The test is not testing that read-only properties are not overwritten, but that defineProperty works.