archives

« Bugzilla Issues Index

#2488 — 6.1.7.3, 9.4.3: String exotic objects can violate [[GetOwnProperty]] invariant


6.1.7.3 Invariants of the Essential Internal Methods, [[GetOwnProperty]] (P):

> If the target is non-extensible and P is non-existent,
> then all future calls to [[GetOwnProperty]] (P) must
> describe P as non-existent (i.e. [[GetOwnProperty]] (P)
> must return undefined)

This invariant can be violated by String exotic objects when an uninitialised string object is made non-extensible and then later initialised.


Test case:
---
// Create uninitialised string object and define its "length" property
let str = String[Symbol.create]();
Reflect.defineProperty(str, "length", {value: 1, writable: false, enumerable: false, configurable: false});

// Make string object non-extensible, observe "0" property
Reflect.preventExtensions(str);
let observedDesc = Reflect.getOwnPropertyDescriptor(str, "0");
print(`IsExtensible(str) = ${Reflect.isExtensible(str)}`);
print(`(1) str.[[GetOwnProperty]]("0") = ${JSON.stringify(observedDesc)}`);

// Initialise string object and retrieve "0" property
String.call(str, "A");
let currentDesc = Reflect.getOwnPropertyDescriptor(str, "0");
print(`(2) str.[[GetOwnProperty]]("0") = ${JSON.stringify(currentDesc)}`);
---

Output:
---
IsExtensible(str) = false
(1) str.[[GetOwnProperty]]("0") = undefined
(2) str.[[GetOwnProperty]]("0") = {"value":"A","writable":false,"enumerable":true,"configurable":false}
---

Expected:
Second [[GetOwnProperty]] also needs to report `undefined` to fulfil the [[GetOwnProperty]] invariant.


Cool, I think this means the I need to tweak the exotic array internal methods to ensure that the invariant is maintained.


or, just tweak the String constructor to throw if an uninitialized string is non-extensible.


fixed in rev26 editor's draft


in rev26