mirror of
https://github.com/tokio-rs/bytes.git
synced 2026-08-27 00:00:17 +02:00
Assert the LSB is 0 when converting Vec into Bytes
This commit is contained in:
+29
-3
@@ -257,8 +257,20 @@ impl Bytes {
|
|||||||
let sub_p = subset.as_ptr() as usize;
|
let sub_p = subset.as_ptr() as usize;
|
||||||
let sub_len = subset.len();
|
let sub_len = subset.len();
|
||||||
|
|
||||||
assert!(sub_p >= bytes_p);
|
assert!(
|
||||||
assert!(sub_p + sub_len <= bytes_p + bytes_len);
|
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;
|
let sub_offset = sub_p - bytes_p;
|
||||||
|
|
||||||
@@ -719,6 +731,12 @@ impl From<Vec<u8>> for Bytes {
|
|||||||
let slice = vec.into_boxed_slice();
|
let slice = vec.into_boxed_slice();
|
||||||
let len = slice.len();
|
let len = slice.len();
|
||||||
let ptr = slice.as_ptr();
|
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));
|
drop(Box::into_raw(slice));
|
||||||
|
|
||||||
let data = ptr as usize | KIND_VEC;
|
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> {
|
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 buf = (shared as usize & !KIND_MASK) as *mut u8;
|
||||||
let cap = (offset as usize - buf as usize) + len;
|
let cap = (offset as usize - buf as usize) + len;
|
||||||
|
|||||||
+18
-2
@@ -829,8 +829,17 @@ fn slice_ref_catches_not_an_empty_subset() {
|
|||||||
#[test]
|
#[test]
|
||||||
#[should_panic]
|
#[should_panic]
|
||||||
fn empty_slice_ref_catches_not_an_empty_subset() {
|
fn empty_slice_ref_catches_not_an_empty_subset() {
|
||||||
let bytes = Bytes::copy_from_slice(&b""[..]);
|
let bytes = Bytes::new();
|
||||||
let slice = &b""[0..0];
|
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);
|
bytes.slice_ref(slice);
|
||||||
}
|
}
|
||||||
@@ -865,3 +874,10 @@ fn bytes_reserve_overflow() {
|
|||||||
|
|
||||||
bytes.reserve(usize::MAX);
|
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);
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user