diff options
author | 2022-04-28 19:37:33 +1000 | |
---|---|---|
committer | 2022-04-28 11:37:33 +0200 | |
commit | 0a2c43af8811fecf6fd08379f16571594bcbb738 (patch) | |
tree | e418ac9c5763d686ff119ce14c5395694742a9be | |
parent | 8198f9e28ebbf59760af25748d18d6a43260edf3 (diff) | |
download | bytes-0a2c43af8811fecf6fd08379f16571594bcbb738.tar.gz bytes-0a2c43af8811fecf6fd08379f16571594bcbb738.tar.zst bytes-0a2c43af8811fecf6fd08379f16571594bcbb738.zip |
Fix bugs in `BytesMut::reserve_inner` (#544)
-rw-r--r-- | src/bytes_mut.rs | 2 | ||||
-rw-r--r-- | tests/test_bytes.rs | 19 |
2 files changed, 20 insertions, 1 deletions
diff --git a/src/bytes_mut.rs b/src/bytes_mut.rs index 88d7f00..cc1a3ba 100644 --- a/src/bytes_mut.rs +++ b/src/bytes_mut.rs @@ -646,7 +646,7 @@ impl BytesMut { self.cap = v.capacity(); } else { // calculate offset - let off = v.capacity() - self.cap; + let off = (self.ptr.as_ptr() as usize) - (v.as_ptr() as usize); // new_cap is calculated in terms of `BytesMut`, not the underlying // `Vec`, so it does not take the offset into account. diff --git a/tests/test_bytes.rs b/tests/test_bytes.rs index 76f6513..a1f0af8 100644 --- a/tests/test_bytes.rs +++ b/tests/test_bytes.rs @@ -527,6 +527,25 @@ fn reserve_in_arc_nonunique_does_not_overallocate() { assert_eq!(2001, bytes.capacity()); } +/// This function tests `BytesMut::reserve_inner`, where `BytesMut` holds +/// a unique reference to the shared vector and decide to reuse it +/// by reallocating the `Vec`. +#[test] +fn reserve_shared_reuse() { + let mut bytes = BytesMut::with_capacity(1000); + bytes.put_slice(b"Hello, World!"); + drop(bytes.split()); + + bytes.put_slice(b"!123ex123,sadchELLO,_wORLD!"); + // Use split_off so that v.capacity() - self.cap != off + drop(bytes.split_off(9)); + assert_eq!(&*bytes, b"!123ex123"); + + bytes.reserve(2000); + assert_eq!(&*bytes, b"!123ex123"); + assert_eq!(bytes.capacity(), 2009); +} + #[test] fn extend_mut() { let mut bytes = BytesMut::with_capacity(0); |