Closed Bug 601329 Opened 14 years ago Closed 12 years ago

ToPropertyDescriptor({}) erroneously completes the property descriptor with missing attributes

Categories

(Core :: JavaScript Engine, defect, P2)

x86
macOS
defect

Tracking

()

RESOLVED FIXED

People

(Reporter: tomvc.be, Unassigned)

References

Details

According to the ES5 spec., ToPropertyDescriptor({}) should return a completely empty property descriptor. The implementation currently seems to auto-complete this descriptor to { value: (void 0), writable: false, enumerable: false, configurable: false }.

Without proxies, I think this was unobservable to JS code, but with the addition of proxies this changes:

var x;
var p = Proxy.create({
  defineProperty: function(name, desc) { x = ('value' in desc); }
});
Object.defineProperty(p, 'foo', {});

x is true while it should be false.
Priority: -- → P2
I would like to draw renewed attention to this open issue:

Problem: property descriptor objects are currently always fully completed before being passed to a proxy handler's defineProperty trap.
The ES5 and harmony:proxies spec do not require the property descriptor to be completed, only for it to be "normalized".
Not completing the descriptor is necessary for proxies to be able to accurately emulate the built-in [[DefineOwnProperty]] algorithm (whose behavior depends on the presence or absence of attributes), and for proxies to be able to handle changes to just a single attribute of an existing property. Consider:

var o = { x: 1 };
Object.defineProperty(o, 'x', { writable: false}); // will only set writable from true to false, and leave other attributes untouched
Object.getOwnPropertyDescriptor(o, 'x').configurable; // is still 'true'

// now try to do the same on a proxy
var target = { x: 1 };
var p = Proxy.create({
  getOwnPropertyDescriptor: function(name) { return Object.getOwnPropertyDescriptor(target, name); },
  defineProperty: function(name, desc) { Object.defineProperty(target, name, desc); return true; }
});
// since desc is completed in the current implementation, the following call will actually be
// interpreted as Object.defineProperty(p, 'x', {writable:false,configurable:false,enumerable:false,value:undefined})
// which is probably not what the programmer intended
Object.defineProperty(p, 'x', { writable: false }); null; // null added to ensure p doesn't need to be printed to the shell
Object.getOwnPropertyDescriptor(p, 'x').configurable; // expected 'true' but is currently 'false'
No longer blocks: harmony:proxy
Need an owner for this bug.

/be
Updated test case:
===
var d;
var p = new Proxy({}, {
  defineProperty: function(target, name, desc) { d = desc; }
});
Object.defineProperty(p, 'foo', {});

console.log('d', d);
===
It works with direct proxies. Closing this bug as fixed.
Blocks: 703537
Status: NEW → RESOLVED
Closed: 12 years ago
Resolution: --- → FIXED
You need to log in before you can comment on or make changes to this bug.