Proxies: wrong "receiver" used in default "set" trap

Allen Wirfs-Brock allen at wirfs-brock.com
Thu Dec 20 12:01:18 PST 2012


below
On Dec 20, 2012, at 2:09 AM, Tom Van Cutsem wrote:

> [+jwalden]
> 
> 2012/12/19 Allen Wirfs-Brock <allen at wirfs-brock.com>
> ...
> 
> Currently, that test is performed in step 5.b. by testing whether the "current" object we are visiting in the proto chain O is the Receiver object. At first sight, this is a rather weird way of deciding between update vs. addition. We can get away with this test because we've just queried the O object for an own property (ownDesc). Hence, if O === Receiver, then we know Receiver already has the same property and we must update, rather than add.
> 
> In the presence of proxies, this test is no longer valid, as Receiver may be a proxy for O.

I don't think this really makes any difference.  A an object and a Proxy for the object are two distinct object and they need to always be treated as such.  The real problem with the SameAs test is that when Receiver and O are different you can't really assume anything about how they relate to each other as  Reflect.set can be called with arbitrary values provided for its target and receiver parameters.

> 
> The right fix (at least, it feels like the obvious right fix to me), is not to test whether O === Receiver, but rather just let the algorithm explicitly test whether the Receiver object already defines an own property with key P, to decide between update vs. addition:
> 
> replace step 5.b with:
> 5.b Let existingDesc be the result of calling the [[GetOwnProperty]] internal method of Receiver with argument P.
> 5.c If existingDesc is not undefined, then
>   ... // same steps as before

Yes, here is the new step 5 as I have just updated it in my spec. draft (ignore the 1, it's really 5) 
If IsDataDescriptor(ownDesc) is true, then
If ownDesc.[[Writable]] is false, return false.
If Type(Receiver) is not Object, return false.
Let existingDescriptor be be the result of calling the [[GetOwnProperty]] internal method of Receiver with argument P.
ReturnIfAbrupt(existingDescriptor).
If existingDescriptor is not undefined, then
Let valueDesc be the Property Descriptor {[[Value]]: V}.
Return the result of calling the [[DefineOwnProperty]] internal method of Receiver with arguments P and valueDesc.
Else Receiver does not currently have a property P,
Return the result of performing CreateOwnDataProperty(Receiver, P, V).

Allen
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20121220/57c97c89/attachment.html>


More information about the es-discuss mailing list