mirror of
https://github.com/tokio-rs/bytes.git
synced 2026-08-25 00:00:22 +02:00
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`.
This commit is contained in:
committed by
Sean McArthur
parent
87b75cce16
commit
f330ef6c4d
@@ -270,6 +270,12 @@ impl Bytes {
|
|||||||
/// Requires that the given `sub` slice is in fact contained within the
|
/// Requires that the given `sub` slice is in fact contained within the
|
||||||
/// `Bytes` buffer; otherwise this function will panic.
|
/// `Bytes` buffer; otherwise this function will panic.
|
||||||
pub fn slice_ref(&self, subset: &[u8]) -> Bytes {
|
pub fn slice_ref(&self, subset: &[u8]) -> Bytes {
|
||||||
|
// Empty slice and empty Bytes may have their pointers reset
|
||||||
|
// so explicitly allow empty slice to be a subslice of any slice.
|
||||||
|
if subset.is_empty() {
|
||||||
|
return Bytes::new();
|
||||||
|
}
|
||||||
|
|
||||||
let bytes_p = self.as_ptr() as usize;
|
let bytes_p = self.as_ptr() as usize;
|
||||||
let bytes_len = self.len();
|
let bytes_len = self.len();
|
||||||
|
|
||||||
|
|||||||
+14
-15
@@ -808,6 +808,16 @@ fn slice_ref_empty() {
|
|||||||
assert_eq!(&sub[..], b"");
|
assert_eq!(&sub[..], b"");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn slice_ref_empty_subslice() {
|
||||||
|
let bytes = Bytes::from(&b"abcde"[..]);
|
||||||
|
let subbytes = bytes.slice(0..0);
|
||||||
|
let slice = &subbytes[..];
|
||||||
|
// The `slice` object is derived from the original `bytes` object
|
||||||
|
// so `slice_ref` should work.
|
||||||
|
assert_eq!(Bytes::new(), bytes.slice_ref(slice));
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[should_panic]
|
#[should_panic]
|
||||||
fn slice_ref_catches_not_a_subset() {
|
fn slice_ref_catches_not_a_subset() {
|
||||||
@@ -818,30 +828,19 @@ fn slice_ref_catches_not_a_subset() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[should_panic]
|
fn slice_ref_not_an_empty_subset() {
|
||||||
fn slice_ref_catches_not_an_empty_subset() {
|
|
||||||
let bytes = Bytes::from(&b"012345678"[..]);
|
let bytes = Bytes::from(&b"012345678"[..]);
|
||||||
let slice = &b""[0..0];
|
let slice = &b""[0..0];
|
||||||
|
|
||||||
bytes.slice_ref(slice);
|
assert_eq!(Bytes::new(), bytes.slice_ref(slice));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[should_panic]
|
fn empty_slice_ref_not_an_empty_subset() {
|
||||||
fn empty_slice_ref_catches_not_an_empty_subset() {
|
|
||||||
let bytes = Bytes::new();
|
let bytes = Bytes::new();
|
||||||
let slice = &b"some other slice"[0..0];
|
let slice = &b"some other slice"[0..0];
|
||||||
|
|
||||||
// Protect this test against Bytes internals.
|
assert_eq!(Bytes::new(), bytes.slice_ref(slice));
|
||||||
//
|
|
||||||
// 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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|||||||
Reference in New Issue
Block a user