-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Workaround for a TextDecoder bug in Safari causing a RangeError to be thrown #4472
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
Conversation
@@ -11,16 +11,16 @@ | |||
(type (;9;) (func (param i32 f64))) | |||
(import "./reference_test_bg.js" "__wbindgen_init_externref_table" (func (;0;) (type 0))) | |||
(func $__wbindgen_realloc (;1;) (type 8) (param i32 i32 i32 i32) (result i32)) | |||
(func $__wbindgen_malloc (;2;) (type 6) (param i32 i32) (result i32)) |
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.
I am not sure why I needed these changes. I am using rustc 1.86.0, maybe I should be using another version?
06346fa
to
1a75ba6
Compare
Some unrelated clippy lints are failing, has CI rustc been updated without updating the code? |
There don't seem to be any tests (generated .js-files) that use the non-browser path of |
1a75ba6
to
20a27e6
Compare
@daxpedda do you have any input on these? The PR works around a critical bug on Safari and would be very useful for many people! |
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.
I'm a tiny bit concerned about the 1MiB margin. This comment shows that it fails at 2,147,483,600 bytes and succeeds at 2,147,483,500 bytes. So the margin should be between 148 and 47 bytes.
Considering how reproducable this test looks like, it would be nice to find out the exact number it fails at. The precise number is actually not that important, it would just be nice to once and for all establish that it actually fails at a certain number and that its not flaky or anything.
In any case, until somebody finds the time to actually try this out we will leave it at the current 1MiB margin considering that there is real-world data behind it.
20a27e6
to
056a294
Compare
I tried a small margin at first but could not get it to work on my machine, so I grabbed a margin which I thought was large enough to avoid problems but small enough to not have any significance (1 MiB is 0.049% of 2GiB) |
If you can actually try it, could you do the following: const decoder = new TextDecoder()
const buffer1 = new ArrayBuffer(100)
for (let i = 0; i < 21474836; i++) {
decoder.decode(buffer1)
}
const buffer2 = new ArrayBuffer(1)
let i = 2147483601
try {
for (; i <= 2147483648; i++) {
decoder.decode(buffer2)
}
} catch {
console.err(`failed at ${i} number of bytes`)
} And check if it fails consistently at the same number of bytes. |
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.
I keep forgetting this: please add an entry to the changelog as well!
… thrown `TextDecoder` in Safari has a limitation that causes it to throw `RangeError` after decoding more than 2GiB of data. This causes long running wasm programs that need to use `TextDecoder` to crash and start throwing `RuntimeError` with the message "Out of bounds memory access". We work around the issue by tracking how much data has been decoded by any given `TextDecoder`, and replace it when it comes close to 2GiB, deducting a small margin of 1MiB which has been empirically shown to reduce the likelihood of miscounting (for unknown reasons) causing a `RangeError` to be thrown. This commit also adds stricter handling of the kind of declaration used for TextDecoder and TextEncoder - TextDecoder always uses let because it needs to be mutable, and TextEncoder always uses const because it doesn't need to be mutable. Fixes wasm-bindgen#4471
056a294
to
e0b6124
Compare
Added a line in the changelog.
I'm on vacation right now, supposed to go on a day trip, so pushing these change kinda in between packing. I would appreciate if we can skip this for now :) |
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.
I'm on vacation right now, supposed to go on a day trip, so pushing these change kinda in between packing. I would appreciate if we can skip this for now :)
Absolutely!
I not yet back to maintaining My 2¢: making a release is relatively low cost so I favor making one as soon as requested. |
Is there an ideal way to make such a request? Should I open a new issue for that, or do other maintainers read closed PR? |
You asking for it here was the request. |
TextDecoder
in Safari has a limitation that causes it to throwRangeError
after decoding more than 2GiB of data. This causes long running wasm programs that need to useTextDecoder
to crash and start throwingRuntimeError
with the message "Out of bounds memory access".We work around the issue by tracking how much data has been decoded by any given
TextDecoder
, and replace it when it comes close to 2GiB, deducting a small margin of 1MiB which has been empirically shown to reduce the likelihood of miscounting (for unknown reasons) causing aRangeError
to be thrown.This commit also adds stricter handling of the kind of declaration used for TextDecoder and TextEncoder - TextDecoder always uses let because it needs to be mutable, and TextEncoder always uses const because it doesn't need to be mutable.
Fixes #4471