"compatible descriptors" and how they are checked

# David Bruant (13 years ago)

In the current state of the strawman [1], one security invariants for getOwnPropertyDescriptor is: " if property exists on target, check if the returned descriptor is compatible." I just wish to say on the list that it means that the following case throws:

var p = new Proxy({a:1}, { getOwnPropertyDescriptor: function(target, name){ var desc; if(name in target){ desc = Object.getOwnPropertyDescriptor(target, name); desc.configurable = false; } return desc; } }); Object.getOwnPropertyDescriptor(p, 'a'); // throws

It throws because the proxy attempts to report a configurable property as non-configurable (it may not be clear from the phrasing "check if the returned descriptor is compatible").

Also, the wiki doesn't say how the check is being performed. It shouldn't matter, but if the target is itself a proxy, these details are exposed. It may mean that the getOwnPropertyDescriptor trap of the target is being called. I haven't formally proved it, but it seems that the check could also be performed on the "final target" directly, bypassing intermediary traps. I don't know which is best, but for sure this should be spec'ed to avoid interoperability issues.

David

[1] harmony:direct_proxies#invariant_enforcement

# Tom Van Cutsem (13 years ago)

I think you caught a spec bug, because your example should indeed throw, yet it currently doesn't (neither in my harmony-reflect shim nor in Firefox nightly).

The code doesn't throw because the relevant checks for getOwnPropertyDescriptor are currently:

  1. is the returned descriptor d "compatible" in the sense that Object.defineProperty(target,name,d) wouldn't throw a TypeError. And indeed, it is valid to redefine a configurable into a non-configurable descriptor, so this check passes.
  2. if the returned descriptor is non-configurable, check if the property does exist on the target. Since the property exists, this check passes as well.

Check no. 2 should be strengthened to: if the returned descriptor is non-configurable, check if the property does exist as a non-configurable property on the target. Just checking for presence/absence is not strong enough, as your example demonstrates.

Other than that: yes, in order to perform the check, the proxy will call [[GetOwnProperty]] on the target, which is observable if the target is itself a proxy, but that is already specified in the draft Proxy spec.

# Jason Orendorff (13 years ago)

On Wed, Sep 19, 2012 at 4:44 AM, David Bruant <bruant.d at gmail.com> wrote:

Also, the wiki doesn't say how the check is being performed.

harmony:proxies_spec

TrapGetOwnProperty specifies how the check is performed.

# David Bruant (13 years ago)

Le 19/09/2012 13:48, Jason Orendorff a écrit :

On Wed, Sep 19, 2012 at 4:44 AM, David Bruant <bruant.d at gmail.com> wrote:

Also, the wiki doesn't say how the check is being performed. harmony:proxies_spec

TrapGetOwnProperty specifies how the check is performed.

Indeed, my mistake. So the answer to my earlier is that the action is performed on the target directly. "Return the result of calling the built-in function Reflect.getOwnPropertyDescriptor(target, P)." This means that if the target itself is a proxy, its getOwnPropertyDescriptor trap will be called.

Once again, just to state how things are, all algorithms in the harmony:proxies_spec page will have the largest part of their internal revealed if either the target or the handler are themselves proxies. It may necessitate a careful review of each algorithm before adding them to the spec.

# Tom Van Cutsem (13 years ago)

2012/9/19 David Bruant <bruant.d at gmail.com>

Once again, just to state how things are, all algorithms in the harmony:proxies_spec page will have the largest part of their internal revealed if either the target or the handler are themselves proxies. It may necessitate a careful review of each algorithm before adding them to the spec.

Absolutely. This reminds me that Jason spotted a couple of places where the current spec algorithms actually redundantly query the [[Target]]. For instance: at one point an algorithm may check whether a property exists on the target by calling [[HasOwnProperty]], and later it checks whether that property is non-configurable by calling [[GetOwnProperty]]. A single [[GetOwnProperty]] call would suffice to perform both checks. I intend to go over the algorithms and remove those redundancies shortly.