archives

« Bugzilla Issues Index

#2382 — 6.2.4: Current PropertyDescriptor.[[Origin]] design hazards


The [[Origin]] field for PropertyDescriptor records seems to cause more harm than it brings benefits, at least in its current design. IIRC [[Origin]] was added to reduce object allocation costs and to provide a way to use custom property descriptors. But with its current design it is also possible to return invalid property descriptors from `Object.getOwnPropertyDescriptor()`, which does not seem to be intended.

This test case from [1] currently prints "false", which gives the impression that the property is non-configurable when in fact it is configurable.
---
let propertyName = "propertyName";
let target = {[propertyName]: 0};
let p2 = new Proxy(target, {
getOwnPropertyDescriptor(t, pk) {
return {
value: 1, writable: true, enumerable: true,
get configurable() {
delete this.configurable;
this.configurable = false;
return true;
}
};
}
});
print(Object.getOwnPropertyDescriptor(p2, propertyName).configurable);
---

[1] https://github.com/anba/es6draft/blob/master/src/test/scripts/suite/objects/Proxy/origin_pitfalls.js


What harm is there in this?

What was intended is that a Proxy handler can generate and accept (at the object level) any sort of property descriptor is wants. Including ones that add new attributes or has attribute combinations (set+writable) that aren't produced by ordinary objects. These are exactly the sorts of things that extensions to the ES ordinary object model might do. So this allow such extensions to be experimented with and polyfilled.

We could restrict the property descriptors to returned from [[GetOwnProperty]] to only containing data properties. But it isn't clear to me why why is necessary. It has always been the case that property descritpros using accessor properties could be passed to Object.defineProperty, etc. And a property descriptor itself might be a Proxy so restricting accessor properties still don't result in side-effect free access to property descriptors.

We already have a good separation between Property Descriptor Records which are used internally within the spec. and Property Descriptor Objects which are at the Es meta level. I don't see why the object form needs to be restricted. When internal invariants need to be maintained Descriptor records are generated from descriptor objects.


I've just noticed this topic was already discussed in [1]. Basically I share the same concerns as Tom Van Cutsem (cc-ed), so I don't think it's necessary for me to repeat them here once again. I've also cc-ed Mark Miller because he was explicitly mentioned in that thread.

[1] http://esdiscuss.org/topic/property-descriptor-normalization-was-general-comments-response-was-re-es6-rev13-review-mop-refactoring-symbols-proxies-reflect-module


These issues were brought up independently by Jason Orendorff [1]

After discussion between MarkM, Allen and myself, the consensus is to remove [[Origin]] and instead spec [[GetOwnProperty]] for Proxies such that the descriptor returned by the trap is coerced into a fresh, normalized, complete descriptor object (as originally specified in [2], but without copying custom attributes).

[1] http://esdiscuss.org/topic/object-getownpropertydescriptor-can-return-just-about-anything
[2] http://wiki.ecmascript.org/doku.php?id=harmony:proxies_spec


in rev26