From 60cbb776f22e4ef2268c026e88a24d6ed75b3776 Mon Sep 17 00:00:00 2001 From: discord9 <55937128+discord9@users.noreply.github.com> Date: Fri, 14 Nov 2025 17:52:50 +0800 Subject: [PATCH] fix: `BytesMut` only reuse if src has remaining (#803) Signed-off-by: discord9 --- src/bytes_mut.rs | 7 +++++-- tests/test_buf_mut.rs | 9 +++++++++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/bytes_mut.rs b/src/bytes_mut.rs index 333a0ae..565e91d 100644 --- a/src/bytes_mut.rs +++ b/src/bytes_mut.rs @@ -1202,8 +1202,11 @@ unsafe impl BufMut for BytesMut { where Self: Sized, { - // When capacity is zero, try reusing allocation of `src`. - if self.capacity() == 0 { + if !src.has_remaining() { + // prevent calling `copy_to_bytes`->`put`->`copy_to_bytes` infintely when src is empty + return; + } else if self.capacity() == 0 { + // When capacity is zero, try reusing allocation of `src`. let src_copy = src.copy_to_bytes(src.remaining()); drop(src); match src_copy.try_into_mut() { diff --git a/tests/test_buf_mut.rs b/tests/test_buf_mut.rs index 9eb0bff..f1bd3b0 100644 --- a/tests/test_buf_mut.rs +++ b/tests/test_buf_mut.rs @@ -273,3 +273,12 @@ fn copy_from_slice_panics_if_different_length_2() { let slice = unsafe { UninitSlice::from_raw_parts_mut(data.as_mut_ptr(), 3) }; slice.copy_from_slice(b"abcd"); } + +/// Test if with zero capacity BytesMut does not infinitely recurse in put from Buf +#[test] +fn test_bytes_mut_reuse() { + let mut buf = BytesMut::new(); + buf.put(&[] as &[u8]); + let mut buf = BytesMut::new(); + buf.put(&[1u8, 2, 3] as &[u8]); +}