diff options
-rw-r--r-- | src/bytes.rs | 32 | ||||
-rw-r--r-- | tests/test_bytes.rs | 20 |
2 files changed, 47 insertions, 5 deletions
diff --git a/src/bytes.rs b/src/bytes.rs index 08ae3c7..e2f08b5 100644 --- a/src/bytes.rs +++ b/src/bytes.rs @@ -257,8 +257,20 @@ impl Bytes { let sub_p = subset.as_ptr() as usize; let sub_len = subset.len(); - assert!(sub_p >= bytes_p); - assert!(sub_p + sub_len <= bytes_p + bytes_len); + assert!( + sub_p >= bytes_p, + "subset pointer ({:p}) is smaller than self pointer ({:p})", + sub_p as *const u8, + bytes_p as *const u8, + ); + assert!( + sub_p + sub_len <= bytes_p + bytes_len, + "subset is out of bounds: self = ({:p}, {}), subset = ({:p}, {})", + bytes_p as *const u8, + bytes_len, + sub_p as *const u8, + sub_len, + ); let sub_offset = sub_p - bytes_p; @@ -719,6 +731,12 @@ impl From<Vec<u8>> for Bytes { let slice = vec.into_boxed_slice(); let len = slice.len(); let ptr = slice.as_ptr(); + + assert!( + ptr as usize & KIND_VEC == 0, + "Vec pointer should not have LSB set: {:p}", + ptr, + ); drop(Box::into_raw(slice)); let data = ptr as usize | KIND_VEC; @@ -808,7 +826,15 @@ unsafe fn shared_drop(data: &mut AtomicPtr<()>, ptr: *const u8, len: usize) { } unsafe fn rebuild_vec(shared: *const (), offset: *const u8, len: usize) -> Vec<u8> { - debug_assert_eq!(shared as usize & KIND_MASK, KIND_VEC); + debug_assert!( + shared as usize & KIND_MASK == KIND_VEC, + "rebuild_vec should have beeen called with KIND_VEC", + ); + debug_assert!( + shared as usize & !KIND_MASK != 0, + "rebuild_vec should be called with non-null pointer: {:p}", + shared, + ); let buf = (shared as usize & !KIND_MASK) as *mut u8; let cap = (offset as usize - buf as usize) + len; diff --git a/tests/test_bytes.rs b/tests/test_bytes.rs index 535b2fa..b582627 100644 --- a/tests/test_bytes.rs +++ b/tests/test_bytes.rs @@ -829,8 +829,17 @@ fn slice_ref_catches_not_an_empty_subset() { #[test] #[should_panic] fn empty_slice_ref_catches_not_an_empty_subset() { - let bytes = Bytes::copy_from_slice(&b""[..]); - let slice = &b""[0..0]; + let bytes = Bytes::new(); + let slice = &b"some other slice"[0..0]; + + // Protect this test against Bytes internals. + // + // This should panic *because* the slice's ptr doesn't fit in the range + // of the `bytes`. + if bytes.as_ptr() as usize == slice.as_ptr() as usize { + // don't panic, failing the test + return; + } bytes.slice_ref(slice); } @@ -865,3 +874,10 @@ fn bytes_reserve_overflow() { bytes.reserve(usize::MAX); } + +#[test] +fn bytes_with_capacity_but_empty() { + // See https://github.com/tokio-rs/bytes/issues/340 + let vec = Vec::with_capacity(1); + let _ = Bytes::from(vec); +} |