I think too much validation is not a good idea. Let the proxy lie. If you 
don't, what is the purpose of Proxy? I have a case where I wanted to force 
every new property to be read-only through a Proxy so that, once created, they 
can no longer change. But I get "TypeError" because of such a validation:

```js
"use strict";
const proxy = new Proxy({}, {
        set(target, property, value, receiver) {
                if (Object.prototype.hasOwnProperty.call(target, property)) 
return false;
                Object.defineProperty(target, property, {configurable: false, 
enumerable: true, writable: false, value: value});
                return true;
        },
        defineProperty(target, property, descriptor) {
                if (Object.prototype.hasOwnProperty.call(target, property)) 
return false;
                descriptor = Object.assign({}, descriptor, {configurable: 
false, enumerable: true});
                if (!descriptor.get && !descriptor.set) descriptor.writable = 
false;
                Object.defineProperty(target, property, descriptor);
                return true;
        },
});

proxy.a = 1;
proxy.a = 2; // TypeError: 'set' on proxy: trap returned falsish for property 
'a'

Object.defineProperty(proxy, 'b', {value: 3});
Object.defineProperty(proxy, 'b', {value: 4}); // TypeError: 'defineProperty' 
on proxy: trap returned falsish for property 'b'
```

-----Original Message-----
From: Claude Pache [mailto:[email protected]] 
Sent: Tuesday, August 09, 2016 8:44 AM
To: es-discuss <[email protected]>
Cc: Mark S. Miller <[email protected]>; Raul-Sebastian Mihăilă 
<[email protected]>
Subject: Re: Object.freezing proxies should freeze or throw?

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
[email protected]
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to