If the final length is a value >= 2^32 then attempting to set it on an array object will throw a RangeError. However note, that this special behavior is only for array objects. If push is used generically with non-array objects then "n" can reach a greater value and the final length will be set appropriately. Where a wrap could occur would be if the push or another similar array method was subsequently applied to such a non object with a huge length property value. These methods generally apply ToUnit32 to the length value when they initially retrieve it. So operations upon a non-array object with a huge length will start at some warped position.
This is the same in both ES3 and ES5. I'd argue that the initial ToUint32 in these algorithms is really a bug that wasn't caught long ago. For real arrays its is unnecessary as the special internal method treatment guarantee's it is already a uint32 and is unnecessary. For non-arrays there are the array methods don't generally clamp either indices or length values to 32-bits on stores. So the initial to uint32 at the beginning of these algorithms is unnecessary for real arrays and is potentially corrupting for non arrays. It probably really should be doing a ToInteger (or perhaps the non-existent ToUInteger) to guarantee it is working with an integer length.
This problem occurs in most of the array methods.
fixed in rev17 editor's draft
fixed in rev17, August 23, 2013 draft