Skip to content

Commit f330ef6

Browse files
stepanchegseanmonstar
authored andcommitted
Do not panic on Bytes::slice_ref on empty slice (#355)
Use case: ``` let bytes: Bytes = ... let subbytes = bytes.slice(a..b); // where a == b let slice = &subbytes[..]; let slice_bytes = bytes.slice_ref(slice); ``` Last line should not panic, because `slice` object is derived from the original `Bytes` object. Before this commit it panics, because `Bytes::slice` returns a fresh `Bytes` object when `begin == end`.
1 parent 87b75cc commit f330ef6

File tree

2 files changed

+20
-15
lines changed

2 files changed

+20
-15
lines changed

src/bytes.rs

+6
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,12 @@ impl Bytes {
270270
/// Requires that the given `sub` slice is in fact contained within the
271271
/// `Bytes` buffer; otherwise this function will panic.
272272
pub fn slice_ref(&self, subset: &[u8]) -> Bytes {
273+
// Empty slice and empty Bytes may have their pointers reset
274+
// so explicitly allow empty slice to be a subslice of any slice.
275+
if subset.is_empty() {
276+
return Bytes::new();
277+
}
278+
273279
let bytes_p = self.as_ptr() as usize;
274280
let bytes_len = self.len();
275281

tests/test_bytes.rs

+14-15
Original file line numberDiff line numberDiff line change
@@ -808,6 +808,16 @@ fn slice_ref_empty() {
808808
assert_eq!(&sub[..], b"");
809809
}
810810

811+
#[test]
812+
fn slice_ref_empty_subslice() {
813+
let bytes = Bytes::from(&b"abcde"[..]);
814+
let subbytes = bytes.slice(0..0);
815+
let slice = &subbytes[..];
816+
// The `slice` object is derived from the original `bytes` object
817+
// so `slice_ref` should work.
818+
assert_eq!(Bytes::new(), bytes.slice_ref(slice));
819+
}
820+
811821
#[test]
812822
#[should_panic]
813823
fn slice_ref_catches_not_a_subset() {
@@ -818,30 +828,19 @@ fn slice_ref_catches_not_a_subset() {
818828
}
819829

820830
#[test]
821-
#[should_panic]
822-
fn slice_ref_catches_not_an_empty_subset() {
831+
fn slice_ref_not_an_empty_subset() {
823832
let bytes = Bytes::from(&b"012345678"[..]);
824833
let slice = &b""[0..0];
825834

826-
bytes.slice_ref(slice);
835+
assert_eq!(Bytes::new(), bytes.slice_ref(slice));
827836
}
828837

829838
#[test]
830-
#[should_panic]
831-
fn empty_slice_ref_catches_not_an_empty_subset() {
839+
fn empty_slice_ref_not_an_empty_subset() {
832840
let bytes = Bytes::new();
833841
let slice = &b"some other slice"[0..0];
834842

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-
}
843-
844-
bytes.slice_ref(slice);
843+
assert_eq!(Bytes::new(), bytes.slice_ref(slice));
845844
}
846845

847846
#[test]

0 commit comments

Comments
 (0)