Skip to content

Commit 8733f74

Browse files
committed
Assert the LSB is 0 when converting Vec into Bytes
1 parent 17a8ac9 commit 8733f74

File tree

2 files changed

+47
-5
lines changed

2 files changed

+47
-5
lines changed

src/bytes.rs

+29-3
Original file line numberDiff line numberDiff line change
@@ -257,8 +257,20 @@ impl Bytes {
257257
let sub_p = subset.as_ptr() as usize;
258258
let sub_len = subset.len();
259259

260-
assert!(sub_p >= bytes_p);
261-
assert!(sub_p + sub_len <= bytes_p + bytes_len);
260+
assert!(
261+
sub_p >= bytes_p,
262+
"subset pointer ({:p}) is smaller than self pointer ({:p})",
263+
sub_p as *const u8,
264+
bytes_p as *const u8,
265+
);
266+
assert!(
267+
sub_p + sub_len <= bytes_p + bytes_len,
268+
"subset is out of bounds: self = ({:p}, {}), subset = ({:p}, {})",
269+
bytes_p as *const u8,
270+
bytes_len,
271+
sub_p as *const u8,
272+
sub_len,
273+
);
262274

263275
let sub_offset = sub_p - bytes_p;
264276

@@ -719,6 +731,12 @@ impl From<Vec<u8>> for Bytes {
719731
let slice = vec.into_boxed_slice();
720732
let len = slice.len();
721733
let ptr = slice.as_ptr();
734+
735+
assert!(
736+
ptr as usize & KIND_VEC == 0,
737+
"Vec pointer should not have LSB set: {:p}",
738+
ptr,
739+
);
722740
drop(Box::into_raw(slice));
723741

724742
let data = ptr as usize | KIND_VEC;
@@ -808,7 +826,15 @@ unsafe fn shared_drop(data: &mut AtomicPtr<()>, ptr: *const u8, len: usize) {
808826
}
809827

810828
unsafe fn rebuild_vec(shared: *const (), offset: *const u8, len: usize) -> Vec<u8> {
811-
debug_assert_eq!(shared as usize & KIND_MASK, KIND_VEC);
829+
debug_assert!(
830+
shared as usize & KIND_MASK == KIND_VEC,
831+
"rebuild_vec should have beeen called with KIND_VEC",
832+
);
833+
debug_assert!(
834+
shared as usize & !KIND_MASK != 0,
835+
"rebuild_vec should be called with non-null pointer: {:p}",
836+
shared,
837+
);
812838

813839
let buf = (shared as usize & !KIND_MASK) as *mut u8;
814840
let cap = (offset as usize - buf as usize) + len;

tests/test_bytes.rs

+18-2
Original file line numberDiff line numberDiff line change
@@ -829,8 +829,17 @@ fn slice_ref_catches_not_an_empty_subset() {
829829
#[test]
830830
#[should_panic]
831831
fn empty_slice_ref_catches_not_an_empty_subset() {
832-
let bytes = Bytes::copy_from_slice(&b""[..]);
833-
let slice = &b""[0..0];
832+
let bytes = Bytes::new();
833+
let slice = &b"some other slice"[0..0];
834+
835+
// Protect this test against Bytes internals.
836+
//
837+
// This should panic *because* the slice's ptr doesn't fit in the range
838+
// of the `bytes`.
839+
if bytes.as_ptr() as usize == slice.as_ptr() as usize {
840+
// don't panic, failing the test
841+
return;
842+
}
834843

835844
bytes.slice_ref(slice);
836845
}
@@ -865,3 +874,10 @@ fn bytes_reserve_overflow() {
865874

866875
bytes.reserve(usize::MAX);
867876
}
877+
878+
#[test]
879+
fn bytes_with_capacity_but_empty() {
880+
// See https://github.com/tokio-rs/bytes/issues/340
881+
let vec = Vec::with_capacity(1);
882+
let _ = Bytes::from(vec);
883+
}

0 commit comments

Comments
 (0)