fix(core): cap adaptive buffer initial allocations - #36432
Conversation
bartlomieju
left a comment
There was a problem hiding this comment.
Good catch, and it's reachable: new_from_hint_u64 is fed size hints that can come straight from a Content-Length, so a hostile Content-Length: 18446744073709551615 reached usize::next_power_of_two(usize::MAX) β a panic in debug, and a wrap to 0 in release, which is arguably worse.
The two halves fit together properly: usize::try_from(...).unwrap_or(usize::MAX) stops the as _ truncation on 32-bit targets, and capped_next_power_of_two makes the rounding total. Capping the initial allocation at MAX_GROW_LEN rather than some new constant is the right choice β the strategy already refuses to grow past 16 MiB, so starting above it was inconsistent anyway. A genuinely known 32 MiB body now costs one extra realloc, which is a fine trade for not letting a header pick the allocation size.
Test detail worth noting: (usize::MAX as u64).saturating_add(1) works on both 32- and 64-bit β it's u64::MAX on 64-bit and 2^32 on 32-bit, and both saturate to usize::MAX through try_from. LGTM.
Summary
u64size hints when the targetusizecannot represent themDetails
Adaptive buffer size classes round size hints to a power of two when choosing the initial allocation. Oversized hints could overflow that rounding operation or choose a starting size above the strategy's normal growth ceiling. The initial-size calculation now uses checked rounding and the existing
MAX_GROW_LENcap, while narrower targets convertu64hints without truncation.Validation
./tools/format.js libs/core/io/buffer_strategy.rs --checkcargo test -p deno_core buffer_strategy -- --nocapturecargo check -p deno_core --all-targets