-
Notifications
You must be signed in to change notification settings - Fork 72
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
fix(ses): Distinguish intrinsics in start and non-start compartments #372
Conversation
08ada7b
to
6a3b37f
Compare
88cb07b
to
f5c2e1b
Compare
@kriskowal @warner I hit the "ready for review" button, though I am aware that this needs to be divided into smaller reviewable PRs. Nevertheless, it works, is a big improvement of the status quo, and even seems to work. Comments appreciated, especially on strategy for breaking it up. |
@erights writes:
yay! unsealException restored to its former glory. (actually, I don't see it in erights.org nor https://github.com/kpreid/e-on-java ; did E have |
@kpreid Did you implement something like that? (I remember us talking about it.) |
I implemented sealed exceptions in E-on-CL only.
Let me know if any other pointers would be useful. |
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.
Reverse engineering of this change’s internal chronology:
- Change StaticModuleRecord from class to function.
- Create shared inert StaticModuleRecord.
- Convert Compartment class to Compartment function and prototype
- Rewrite createGlobalObject into initGlobalObject
a. Accept globalObject as an argument instead of creating one on behalf of caller
a. Thread intrinsics and sharedGlobalPropertyNames through initGlobalObject
a. Refactor switch to property loops - Create conventions for referring to distinct intrinsics for start and shared compartments.
a. Reframe taming functions not in terms of “start vs shared” but a single object bag that captures the intrinsics for both environments using %Names%
a. Reframe allow list keys %AllAllowListKeys% - nit: Fix misaligned JSDoc for performEval
- Factor realmRec argument out of createScopeHandler and makeEvaluateFactory. The
realmRec
is cruft from before compartments and we only need the original, “feral” Function constructor from it. Better to just capture that. (Delete realm-rec.js) - nit: Rename XPrototypeConstructor to XOnlyThrows generally.
- Add CompartmentOnlyThrows and StaticModuleRecordOnlyThrows to anonymous intrinsics
- Delete get-named-intrinsic.js
- Delete intrinsics-global.js
- Reframe defineProperty as initProperty
- Factor an “intrinsics manager” out of
getGlobalIntrinsics
. Reuse this part to initialize intrinsics on new global objects for compartments. - Factor
repairIntrinsics
andhardenIntrinsics
out oflockdown
using the intrinsics manager. - Rename the taming modules. (This obscures changes within these modules so needs to be effected in an isolated mechanical commit)
- nit: Fix non-descriptive performEval
x
/source
local variable. - nit: Fix unreported!? linting problem with scope-handler unused
shadow
argument.
@@ -33,8 +33,6 @@ test('identity Array', t => { | |||
|
|||
// Compartment is a shared global | |||
test('identity Compartment', t => { | |||
t.plan(7); |
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.
Should bring this back.
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.
Sigh. I understand why we need it for async tests. But can't we omit it for purely sequential-synchronous tests?
What is |
Your extended comment of how to unpack this PR seems exactly right. Thanks! |
I’ve decided to review this monolithically. That generally means more rounds of back-and-forth, but separating the mechanical changes from the semantic changes will in this case probably take longer than the review. So, I’m releasing the lock on this branch. I may instead push nit fix commits to the end in the process of a local holistic review, but will not force push. |
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.
I’ve left some comments that I resolved myself by pushing commits.
Looks great to me!
packages/ses/test/tame-date.test.js
Outdated
t.assert(Number.isInteger(Date.now())); | ||
t.ok(isDate(new Date())); |
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.
Let’s use ok
instead of assert
throughout. They are aliases.
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.
Addressed with a follow-up commit.
a071709
to
1885370
Compare
8feeea1
to
03791e1
Compare
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.
For some of your comments, github won't let me answer inline.
Answering #372 (comment)
Let’s carry this through or link an issue to track.
See #390
Answering #372 (comment)
Let’s use ok instead of assert throughout. They are aliases.
Addressed with a follow-up commit.
Ok. I made no further changes along these lines. But should we do this everywhere? I like strong "there are very few ways to do that" conventions, so I'd be happier if we did it everywhere.
@@ -33,8 +33,6 @@ test('identity Array', t => { | |||
|
|||
// Compartment is a shared global | |||
test('identity Compartment', t => { | |||
t.plan(7); |
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.
Sigh. I understand why we need it for async tests. But can't we omit it for purely sequential-synchronous tests?
Whitelists no longer painfully redundant.
Placeholder for multiple Compartment constructors, including one which only throws.
Start compartment has initial authority. Others do not. Independent of *Taming options.
{ *Taming: 'unsafe' }
is no longer about initial authority in start compartment, as long as it obeys ocap rules.'unsafe' is now about enabling violations of ocap rules, such as primordials that are no longer powerless.
Lockdown *Taming options have much milder meaning.
dateTaming
is ignored. Maybe we should just get rid of this flag. Transition problem?mathTaming
is ignored. Maybe we should just get rid of this flag. Transition problem?regExpTaming
is effectively ignored. But we may decide that 'unsafe' suppresses the deletion ofRegExp.prototype.compile
.localeTaming
, if set to 'unsafe', leaves the original*Locale*
methods in place.Finally we get to Error taming. Independent of the
errorTaming
option, the tamed powerful v8 API emulation remains on the start compartment'sError
constructor. None of these are on theError
constructor of other compartments. However, this shows that we need a different knob: whether to expose engine-specific (e.g., v8 specific) APIs.In a step towards https://tc39.es/proposal-error-stacks/ , we leave on the start compartment the powerful
getStackString(error)
function, which gives the stacktrace string associated with that error. Because this special power is only on the start compartment, we do not consider it a material violation of ocap rules, so it is there independent oferrorTaming
.The violation of ocap rules which is pervasively available is the legacy behavior of
error.stack
, since it takes no privilege but violates information hiding. Accordingly, on v8 where we have control, undererrorTaming: 'safe'
(or default) this is truncated to the empty string. The 'unsafe' setting leaves the legacy behavior alone, providing the same string that the newgetStackString(error)
provides.Fixes #317
Fixes #385 by getting rid of the realmRec altogether.