Skip to content

Commit

Permalink
Assert the LSB is 0 when converting Vec into Bytes
Browse files Browse the repository at this point in the history
  • Loading branch information
seanmonstar committed Dec 12, 2019
1 parent 17a8ac9 commit 8733f74
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 5 deletions.
32 changes: 29 additions & 3 deletions src/bytes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
20 changes: 18 additions & 2 deletions tests/test_bytes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down Expand Up @@ -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);
}

0 comments on commit 8733f74

Please sign in to comment.