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]); +}