tc39 / ecma262

Status, process, and documents for ECMA-262
https://tc39.es/ecma262/
Other
15k stars 1.28k forks source link

Disallow ArrayBuffers bigger than 2**53 #1032

Closed littledan closed 1 year ago

littledan commented 6 years ago

As pointed out by @verwaest, weird things happen on gigantic ArrayBuffers, where you can't actually address each byte because Numbers can't point to things bigger than 2**53. @verwaest points out a case in interactions with BigInt, but I think there are more mundane cases as well (e.g., running any of the array-derived methods, which assume that you can increment a Number up to the length of the TypedArray).

This is probably not reachable in real implementations because CreateByteDataBlock will throw a RangeError on too-big arguments. I think we should change the specification to throw if you're above 2*53 to prevent the theoretical case where you get outside exact integer territory. Some callsites of CreateByteDataBlock call ToIndex (which will always be in that range) but some don't (e.g., TypedArray constructors called on iterables, though that would take forever*). Maybe this could be fixed by inserting more calls to ToIndex.

rossberg commented 6 years ago

Note that once WebAssembly supports 64-bit address spaces, one of its linear memories might (just as theoretically) be larger than 2^53. So it would no longer be possible to materialise every memory as an ArrayBuffer in JavaScript under that restriction.

littledan commented 6 years ago

I think we're pretty far in the future to get beyond 2^53 bits of memory. We won't be able to use a Number to store things anyway. (Seems like I misunderstood the idea of the other post, clarification)

rossberg commented 6 years ago

Well, we talked about things like supporting mmap and other virtual memory games, so I'm not so sure.

littledan commented 6 years ago

My understanding was that virtual memory in 64-bit systems was commonly a 48-bit address space.

allenwb commented 6 years ago

virtual memory in 64-bit systems was commonly a 48-bit address space.

In which decade?

jfbastien commented 6 years ago

virtual memory in 64-bit systems was commonly a 48-bit address space.

In which decade?

The current decade.

apaprocki commented 6 years ago

... to clarify the above, AMD64 architecture defines a 64-bit virtual address format, of which the low-order 48 bits are used in current implementations.

Don't take it too seriously, but both POWER (Node.js ships for POWER) and SPARC actually use the 64-bit address space and I will admit to having to force memory allocated for SpiderMonkey to fit under the 48-bit limit to not break invariants in the engine. Intel domination creeping into software design... :)

allenwb commented 6 years ago

@jfbastien I hope my irony was obvious. Never write standards for the current decade.

littledan commented 6 years ago

@apaprocki Thanks for that context. I wasn't aware of POWER and SPARC. Still, everything with using ArrayBuffers is currently tied to Number, so until we upgrade them to BigInt, I still think we should do this sort of change.

littledan commented 4 years ago

Sounds like we should go ahead with making this restriction as a PR, with a test262 PR to check for the RangeError, and proposing it to TC39 for consensus. This could be a one-line addition to CreateByteDataBlock. Rather than fix it myself right now, I'd rather leave it as a "good first patch" to any contributor who wants to make a normative change to the JS spec. I'm happy to mentor anyone interested through the process here.

(Thanks for the private ping on this issue, @ljharb !)

mster commented 4 years ago

@littledan Hi there! Is this issue still looking for a contributor? I'd love to work on it :)

Josh-Cena commented 1 year ago

Fixed by #3052