Object.freezing proxies should freeze or throw?

Jordan Harband ljharb at gmail.com
Wed Aug 10 20:24:59 UTC 2016


Only in a Github issue please :-) we shouldn't be using bugs.ecmascript.org
for new issues.

On Wed, Aug 10, 2016 at 1:50 AM, Tom Van Cutsem <tomvc.be at gmail.com> wrote:

> Thanks Claude for your careful review, and for trying to articulate a more
> general principle behind the invariant checks. The lack of such crisp
> principles makes it (too) difficult to verify whether all necessary checks
> are in place.
>
> To clarify, in the case of "update" MOP operations such as defineProperty
> and deleteProperty, your "state B" (the observable state of the target),
> presumably is the state of the target *after* the proxy trap has executed,
> i.e. state B should already reflect the update.
>
> Both the original issue and your new test case with deleteProperty are
> cases where the proxy pretends to have altered the target but has in fact
> not. In a later interaction, the proxy reverts to the original state. This
> violates a client's expectations about when state transitions occur.
>
> Interestingly, the opposite problem, where a proxy does alter the target
> as requested, but then reports that the update failed, is allowed, even
> though this technically also violates a client's expectations about what
> state transitions have occurred. But a failed update leads to a TypeError
> anyway.
>
> At this point, we should probably iron out the details of the fix in a
> GitHub issue or on bugs.ecmascript.org.
>
> Cheers,
> Tom
>
> 2016-08-09 14:44 GMT+02:00 Claude Pache <claude.pache at gmail.com>:
>
>> Given a Proxy that pretends to be in state A while its target is
>> observably in state B, and assuming that the target satisfies the
>> Invariants of the Essential Internal Methods [6.1.7.3], I claim that, in
>> order to force the Proxy to satisfy those Invariants, it is necessary and
>> sufficient to check that the two following conditions hold:
>>
>> * it is legal for an object to pass from state A to state B; and,
>> * it is legal for an object to pass from state B to state A.
>>
>> [6.1.7.3]: https://tc39.github.io/ecma262/#sec-invariants-of-the-
>> essential-internal-methods
>>
>>
>> Because I am too lazy to write the proof just now, I cowardly leave it as
>> an exercice to the reader. Meanwhile, that principle may be used to audit
>> the robustness of the Proxy specification. I have found the following bug
>> in Proxy.[[Delete]]() by applying the above principle to:
>>
>> * state A: nonexistent property on a nonextensible object;
>> * state B: existent own property on a nonextensible object.
>>
>> Resurrection of a successfully deleted property on a nonextensible object:
>>
>> ```js
>> var target = Object.preventExtensions({ x: 1 })
>> var proxy = new Proxy(target, {
>>     deleteProperty() { return true }
>> })
>>
>> Object.isExtensible(proxy) // false
>> delete proxy.x // true
>> proxy.hasOwnProperty('x') // true
>> ```
>>
>> After a first scan, I haven't found other bugs in the essential methods
>> of Proxy, than that one and the missing nonconfigurable-but-writable check
>> in [[GetOwnPropertyDescriptor]] and [[DefineOwnProperty]] already mentioned
>> in that thread.
>>
>> I plan to propose a minimal patch (i.e., just adding the missing checks)
>> in a few days.
>>
>> —Claude
>>
>>
>>
>
> _______________________________________________
> es-discuss mailing list
> es-discuss at mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20160810/4c86bcc8/attachment.html>


More information about the es-discuss mailing list