-
Notifications
You must be signed in to change notification settings - Fork 46
Description
Bug
get_maximum_output_size computes:
16 + 4 + (input_len * 110 / 100)On 32-bit targets (e.g. wasm32 where usize is u32), input_len * 110 overflows when input_len > 2^32 / 110 ≈ 39MB. This causes the function to return a much smaller value than expected.
For example, with input_len = 40_000_000:
- Expected:
44_000_020 - Actual (wasm32):
1_050_347(after overflow wrapping)
This causes compress_into to receive an undersized output buffer, leading to a panic when compressing incompressible data larger than ~39MB.
Minimal reproduction
// Simulating wasm32 (u32) arithmetic:
let input_len: u32 = 40_000_000;
let result = 16 + 4 + (input_len.wrapping_mul(110) / 100);
// result = 1_050_347 (wrong, should be 44_000_020)In practice, this crashes when using diamond-types (CRDT library) compiled to wasm32, which calls compress_into with a buffer allocated via get_maximum_output_size. A document with ~39MB+ of accumulated text content triggers the overflow.
Fix
Rearrange the arithmetic to avoid the intermediate overflow:
16 + 4 + input_len + input_len / 100 * 10 + input_len % 100 * 10 / 100This produces identical results for all inputs but never computes input_len * 110.