I have not responded on list yet because I haven't yet been able to find the time to absorb this thread. But since Allen mentioned it, what I wrote was:
The invariant I am interested in: In a realm where we (the trusted defender who runs first) make Promise defensive as follows * Freeze everything primordial, as SES does * Make a DefensivePromise subclass of Promise that differs minimally, hopefully only by ensuring that its instances are frozen. * "Promise = DefensivePromise;" do "Promise" below refers to DefensivePromise * Freezing whitelisted global properties, as SES currently does for ES5 globals, but for ES6 including "Promise" then it must be the case that Promise.resolve(anything).then(anycallback) for an anything provided by a potential attacker, when executed in the middle of a turn does not call callback during that turn. If it calls anycallback at all, it calls it back *as* a later turn, i.e., in a later turn starting from an empty stack. On Wed, Apr 29, 2015 at 9:49 AM, Allen Wirfs-Brock <al...@wirfs-brock.com> wrote: > > On Apr 29, 2015, at 8:44 AM, C. Scott Ananian wrote: > > On Wed, Apr 29, 2015 at 1:06 AM, Brendan Eich <bren...@mozilla.org> wrote: > >> Kevin Smith wrote: >> >>> So what would the ideal Promise.resolve semantics do? I'm not sure, >>> maybe use SpeciesConstructor instead of [[PromiseConstructor]]? >>> >> >> This removes the wart in my view, has no less integrity. C. Scott? > > > Making this concrete, here would be the new text for 25.4.4.5 > Promise.resolve(x): > >> The resolve function returns either a new promise resolved with the >> passed argument, or the argument itself if the argument is a promise >> produced by this constructor. >> 1. Let C be the this value. >> 2. If IsPromise(x) is true, >> a. Let constructor be the value of SpeciesConstructor(x, %Promise%) > > b. If SameValue(constructor, C) is true, return x. >> 3. If Type(C) is not Object, throw a TypeError exception. >> 4. Let S be Get(C, @@species). >> 5. ReturnIfAbrupt(S). >> 6. If S is neither undefined nor null, let C be S. >> 7. Let promiseCapability be NewPromiseCapability(C) > > [...remainer elided...] > > > Step 2a is the only change. (It was previously "Let constructor be the > value of x's [[PromiseConstructor]] internal slot.") > > > But SpeciesConstructor (or any access to x's @@species) goes through > `x.constructor` and my recollection is that the motivation for adding > [[PromiseConstructor]] was that 'constructor' was not sufficiently tamper > proof. From that perspective, it seems that SpeciesConstructor is actually > worse than just accessing `x.constructor`. > > Also, in a private message Mark Miller mentioned that the primarily > security invariant he's concerned about really relates to the behavior of > the `then` method of the object returned by `Promise.resolve(x)`. Neither > testing `construct` or SpeciesConstructor really tells you anything about > `then`. It seems that the root problem here is trying to apply nominal > type based reasoning to JS. > > Allen > > -- Cheers, --MarkM
_______________________________________________ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss