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