Object.freezing proxies should freeze or throw?
Claude Pache
claude.pache at gmail.com
Tue Aug 9 13:20:01 UTC 2016
> Le 8 août 2016 à 22:35, Tom Van Cutsem <tomvc.be at gmail.com> a écrit :
>
> Claude's additional example is indeed evidence that Object.freeze is not to blame, but rather that the invariant checks of [[GetOwnPropertyDescriptor]] and [[DefineOwnProperty]] are too weak. The culprit is, as far as I can tell, that we re-used the state transitions allowed by DefineOwnProperty, which allows the transition from non-configurable,writable (-c+w) to non-configurable,non-writable (-c-w) and which is unwanted here, as Claude rightfully concludes [to better understand the state transitions involved, see MarkM's lucid state transition chart of property attributes <http://wiki.ecmascript.org/doku.php?id=es3.1:attribute_states <http://wiki.ecmascript.org/doku.php?id=es3.1:attribute_states>>. I wish this diagram were in the spec btw, once you know how to read it, it is significantly easier to understand than the DefineOwnProperty algorithm itself]
>
> I like the simplicity of Claude's suggestion, but I think that check is too tight. Technically if the descriptors are both -c+w data descriptors, their value attributes need not be identical to honor the spec invariants. Instead I would propose to tackle the problem head-on and explicitly disallow a proxy from reporting a -c-w property if the corresponding target property is -c+w. We already have a similar check in place in precisely those two algorithms to test if the configurable attribute matches. It is just a matter of tightening that check to also verify the writable attribute.
>
> This would entail the following changes to the ES2015 spec (new or modified text in bold):
>
>
> 9.5.5 [[GetOwnProperty]] (P)
> ...
> 22. If resultDesc.[[Configurable]] is false, then
> a. If targetDesc is undefined or targetDesc.[[Configurable]] is true, then
> i. Throw a TypeError exception.
> b. If resultDesc.[[Writable]] is false and targetDesc.[[Writable]] is true, then
> i. Throw a TypeError exception.
>
> NOTE [[GetOwnProperty]] for proxy objects enforces the following invariants:
>
> ...
> * A property cannot be reported as non-configurable, non-writable if it exists as a non-configurable, writable own property on the target object.
>
>
> 9.5.6 [[DefineOwnProperty]] (P, Desc)
> ...
> 20. Else targetDesc is not undefined,
> a. If IsCompatiblePropertyDescriptor(extensibleTarget, Desc , targetDesc) is false, throw a TypeError exception.
> b. If settingConfigFalse is true
> i. If targetDesc.[[Configurable]] is true, throw a TypeError exception.
> ii. If Desc.[[Writable]] is false and targetDesc.[[Writable]] is true, throw a TypeError exception.
Rather:
b (unchanged). If settingConfigFalse is true and targetDesc.[[Configurable]] is true, throw a TypeError exception.
c. If targetDesc.[[Configurable]] is false, then
i. If targetDesc.[[Writable]] is true and Desc.[[Writable]] is false, throw a TypeError exception.
because we need the additional check on [[Writable]] when the property is nonconfigurable ("targetDesc.[[Configurable]] is false"), not only when the property is made nonconfigurable ("settingConfigFalse is true").
—Claude
>
> NOTE [[DefineOwnProperty]] for proxy objects enforces the following invariants:
>
> ...
> * A property cannot be successfully set to non-configurable, non-writable if the corresponding own property of the target object is non-configurable, writable.
>
> WDYT?
>
> Regards,
> Tom
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20160809/780c1275/attachment.html>
More information about the es-discuss
mailing list