-
Notifications
You must be signed in to change notification settings - Fork 3.5k
Fix crash in UTF8ToString with resizable ArrayBuffers #27242
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -1078,27 +1078,45 @@ function runtimeKeepalivePop() { | |||||
| return 'runtimeKeepalivePop();'; | ||||||
| } | ||||||
|
|
||||||
| // Some web functions like TextDecoder.decode() may not work with a view of a | ||||||
| // SharedArrayBuffer, see https://github.com/whatwg/encoding/issues/172 | ||||||
| // To avoid that, this function allows obtaining an unshared copy of an | ||||||
| // ArrayBuffer. | ||||||
| // Some web functions like TextDecoder.decode() do not work with a view of a | ||||||
| // SharedArrayBuffer (see https://github.com/whatwg/encoding/issues/172) or of | ||||||
| // a resizable ArrayBuffer (see | ||||||
| // https://github.com/emscripten-core/emscripten/issues/27241). | ||||||
| // To avoid that, this function allows obtaining a copy in those cases. | ||||||
| function getUnsharedTextDecoderView(heap, start, end) { | ||||||
| const shared = `${heap}.slice(${start}, ${end})`; | ||||||
| const unshared = `${heap}.subarray(${start}, ${end})`; | ||||||
| const copy = `${heap}.slice(${start}, ${end})`; | ||||||
| const view = `${heap}.subarray(${start}, ${end})`; | ||||||
|
|
||||||
| // No need to worry about this in non-shared memory builds | ||||||
| if (!SHARED_MEMORY) return unshared; | ||||||
| // The heap can be backed by a resizable ArrayBuffer in non-shared memory | ||||||
| // builds with memory growth enabled. | ||||||
| const maybeResizable = !SHARED_MEMORY && ALLOW_MEMORY_GROWTH && GROWABLE_ARRAYBUFFERS; | ||||||
|
|
||||||
| // If asked to get an unshared view to what we know will be a shared view, or | ||||||
| // if in -Oz, then unconditionally do a .slice() for smallest code size. | ||||||
| // This is guaranteed to work but could be slower since it performs a copy. | ||||||
| if (SHRINK_LEVEL == 2 || heap.startsWith('HEAP')) return shared; | ||||||
| // No need to worry about this in builds where the buffer can be neither | ||||||
| // shared nor resizable. | ||||||
| if (!SHARED_MEMORY && !maybeResizable) return view; | ||||||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's probably neater/simpler to just inline this.
Suggested change
|
||||||
|
|
||||||
| // Otherwise, generate a runtime type check: must do a .slice() if looking at | ||||||
| // a SAB, or can use .subarray() otherwise. Note: We compare with | ||||||
| // `ArrayBuffer` here to avoid referencing `SharedArrayBuffer` which could be | ||||||
| // undefined. | ||||||
| return `${heap}.buffer instanceof ArrayBuffer ? ${unshared} : ${shared}`; | ||||||
| // If in -Oz, then unconditionally do a .slice() for smallest code size. | ||||||
| // This is guaranteed to work but could be slower since it performs a copy. | ||||||
| if (SHRINK_LEVEL == 2) return copy; | ||||||
|
|
||||||
| if (SHARED_MEMORY) { | ||||||
| // If asked to get an unshared view to what we know will be a shared view, | ||||||
| // then unconditionally do a .slice(). | ||||||
| if (heap.startsWith('HEAP')) return copy; | ||||||
|
|
||||||
| // Otherwise, generate a runtime type check: must do a .slice() if looking | ||||||
| // at a SAB, or can use .subarray() otherwise. Note: We compare with | ||||||
| // `ArrayBuffer` here to avoid referencing `SharedArrayBuffer` which could | ||||||
| // be undefined. | ||||||
| return `${heap}.buffer instanceof ArrayBuffer ? ${view} : ${copy}`; | ||||||
| } | ||||||
|
|
||||||
| // With GROWABLE_ARRAYBUFFERS == 2 the heap is always resizable; with | ||||||
| // GROWABLE_ARRAYBUFFERS == 1 resizability is feature-detected at runtime, | ||||||
| // and non-heap views passed to UTF8ArrayToString may not be resizable at | ||||||
| // all, so generate a runtime check in those cases. | ||||||
| if (GROWABLE_ARRAYBUFFERS == 2 && heap.startsWith('HEAP')) return copy; | ||||||
| return `${heap}.buffer.resizable ? ${copy} : ${view}`; | ||||||
| } | ||||||
|
|
||||||
| function getEntryFunction() { | ||||||
|
|
||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2276,13 +2276,13 @@ var JS_BASE64_API = false; | |
| // Enable support for growable views of Wasm memory. This is a recent Web | ||
| // platform feature that can make growing the Wasm memory more efficient, | ||
| // especially in multi-threaded builds. | ||
| // The default setting of 1 will auto-detect the presence of this API and use | ||
| // Setting this to 1 will auto-detect the presence of this API and use | ||
| // it when available. | ||
| // Setting this to 2 will unconditionally require it. This is the only way | ||
| // to completely remove the overhead of growable memory + pthreads. | ||
| // This settings does nothing unless ALLOW_MEMORY_GROWTH is set. | ||
| // [link] | ||
| var GROWABLE_ARRAYBUFFERS = 1; | ||
| var GROWABLE_ARRAYBUFFERS = 0; | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Lets make this a separate PR |
||
|
|
||
| // If the emscripten-generated program is hosted on separate origin then | ||
| // starting new pthread worker can violate CSP rules. Enabling | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.