tokio-rs / bytes

Utilities for working with bytes
MIT License
1.91k stars 288 forks source link

Fix reserve over allocating underlying buffer #560

Closed schultetwin1 closed 2 years ago

schultetwin1 commented 2 years ago

Fixes calls to reserve when the underlying shared buffer was already big enough to fit the requested capacity. Previously a new even larger buffer was created anyways. This could eventually lead to an OOM condition.

Fixes #559

schultetwin1 commented 2 years ago

This appears to have been introduced by #555

schultetwin1 commented 2 years ago

Here is an example of how you could cause an OOM error

#[test]
fn reserve_in_arc_unique_does_not_overallocate_after_multiple_splits() {
    let mut bytes = BytesMut::from(LONG);
    let orig_capacity = bytes.capacity();
    for _ in 0..100 {
        drop(bytes.split_off(LONG.len() / 2));

        // now bytes is Arc and refcount == 1

        let new_capacity = bytes.capacity();
        bytes.reserve(orig_capacity - new_capacity);
    }
    assert_eq!(bytes.capacity(), orig_capacity);
}
schultetwin1 commented 2 years ago

Thanks for the quick merge! And I see you are already prepping a new release (1.2.1), thank you!!