On Jul 14, 2011, at 5:21 AM, Andrew Oakley wrote:
The other complication I've spotted (I think it crops up elsewhere too)
is what to do if n becomes larger than the maximum array index. My
reading of ECMAScript 3 says that we *should* throw a RangeError but
nobody seems to do that.
Opera and Firefox seem to store n as a 32bit unsigned number - the
length wraps and they start putting properties at the beginning of the
array again. I'm not sure what Chrome is doing (I can't find my values
in the returned array), IE says "out of memory" and I got bored waiting
for Safari.
--
Andrew Oakley
This appears to be a (possible) specification bug that first occurs in ES3 and which was not corrected in ES5.
I appears in concat and push. But no other algorithms. The problem occurs when when a length value is incremented and then used as an array index without first applying ToUint32 to the value. It only occurs concat and push because all the other algorithms are bounded by a length value that has had ToUint32 applied to it.
It is probably a bug, because array index based operations generally warp around to 0 at 2^32. I assume that the Firefox implementation was the initial one and it reflects that behavior. However, all array objects (ad generic array like objects) are permitted to have integer property names >= 2^32. These properties are not reflected in the value of the 'length' property (when set by generic array methods for array-like objects). So, there is a slim chance that the specified behavior was intentional in allowing concat and push to leak past the 2^32 element boundary.
We have to possible courses of action:
1) consider the specification to be correct as written.
2) consider this to be a spec. but that we correct in the errata and in future editions.
This is an edge case that probably never occurs in the real world so the choice probably has no real impact. #1 is most consistent with the rest of the ES spec. However, the 2^32 length wrap semantics of arrays is kind of bogus and it might be nice to try to eliminate it in the future. #2 would be a step away from that.
I think we should fix this.
/be