Hi,
What's supposed to happen when one of the built-in methods (e.g.
Array.prototype.push) tries to assign a value greater than 4294967295 to
the length property?
js> a = new Array(4294967295); a.push("foo")
0
i.e. the length becomes 0. This also happens if you apply push to
non-Array instances, which don't have the length property constraint
described in 15.4.
Step 5 of 15.4.4.7 says to "increase n by 1", but it does not say that n
should wrap around to 0 if the new value can't be represented as a
32-bit unsigned integer (the ToUint32 conversion is only done when
assigning the initial value of n, in step 2).
If I interpret the spec correctly, n should become 4294967296, and step
7 should then cause a RangeError when trying to assign the new length.
In the implementations I've tried, this is not the case, and instead you
get this interesting behavior:
js > a = new Array(4294967294); a.push("foo", "bar")
0
js> a[4294967294]
foo
Oops; the length invariant broke. With WebKit:
jsc > a = new Array(4294967294); a.push("foo", "bar")
0
jsc> a[4294967294]
undefined
Oops; all the properties 0,1,2,...,4294967294 were wiped out.
I also question step 2 of 15.4.4.7. Why is the narrow ToUint32
conversion necessary; shouldn't it be a variant of ToInteger? We know
that for Array instances, the invariant on the length property holds
anyway, so the result of the conversion will be the same; but using
ToUint32 makes the function less generic:
js> o = { length: 4294967296 }; Array.prototype.push.call(o, "foo")
1
Pretending I hadn't read the spec, I would have expected the above to
create a property named "4294967296" and increase length by 1; no 32-bit
conversion imposed.
Looking at the other functions in Array.prototype I see that they do
ToUint32 on the length too, so this change might become a bit large and
dangerous. Still, the undefined behavior / data loss irks me.
Best regards,
Kent
_______________________________________________
Es-discuss mailing list
Es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss