Skip to content

Commit

Permalink
Merge pull request #471 from epage/byte
Browse files Browse the repository at this point in the history
fix(stream)!: Prevent slicing on non-UTF8 boundaries
  • Loading branch information
epage authored Feb 12, 2024
2 parents d049ebd + ab48080 commit 46c77dc
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 78 deletions.
6 changes: 3 additions & 3 deletions src/ascii/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ where
I: StreamIsPartial,
I: Stream,
I: Compare<&'static str>,
I: FindSlice<(u8, u8)>,
I: FindSlice<(char, char)>,
<I as Stream>::Token: AsChar + Clone,
{
trace("till_line_ending", move |input: &mut I| {
Expand All @@ -152,10 +152,10 @@ where
I: StreamIsPartial,
I: Stream,
I: Compare<&'static str>,
I: FindSlice<(u8, u8)>,
I: FindSlice<(char, char)>,
<I as Stream>::Token: AsChar + Clone,
{
let res = match take_until::<_, _, ()>(0.., (b'\r', b'\n')).parse_next(input) {
let res = match take_until::<_, _, ()>(0.., ('\r', '\n')).parse_next(input) {
Ok(slice) => slice,
Err(ErrMode::Incomplete(err)) => {
return Err(ErrMode::Incomplete(err));
Expand Down
122 changes: 47 additions & 75 deletions src/stream/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2194,20 +2194,6 @@ impl<'a, 'b> Compare<AsciiCaseless<&'b str>> for &'a str {
}
}

impl<'a> Compare<u8> for &'a str {
#[inline(always)]
fn compare(&self, t: u8) -> CompareResult {
self.as_bytes().compare(t)
}
}

impl<'a> Compare<AsciiCaseless<u8>> for &'a str {
#[inline(always)]
fn compare(&self, t: AsciiCaseless<u8>) -> CompareResult {
self.as_bytes().compare(t)
}
}

impl<'a> Compare<char> for &'a str {
#[inline(always)]
fn compare(&self, t: char) -> CompareResult {
Expand All @@ -2222,20 +2208,6 @@ impl<'a> Compare<AsciiCaseless<char>> for &'a str {
}
}

impl<'a, 'b> Compare<&'b [u8]> for &'a str {
#[inline(always)]
fn compare(&self, t: &'b [u8]) -> CompareResult {
self.as_bytes().compare(t)
}
}

impl<'a, 'b> Compare<AsciiCaseless<&'b [u8]>> for &'a str {
#[inline(always)]
fn compare(&self, t: AsciiCaseless<&'b [u8]>) -> CompareResult {
self.as_bytes().compare(t)
}
}

impl<'a, T> Compare<T> for &'a Bytes
where
&'a [u8]: Compare<T>,
Expand Down Expand Up @@ -2340,6 +2312,48 @@ impl<'i, 's> FindSlice<(&'s [u8], &'s [u8], &'s [u8])> for &'i [u8] {
}
}

impl<'i> FindSlice<char> for &'i [u8] {
#[inline(always)]
fn find_slice(&self, substr: char) -> Option<crate::lib::std::ops::Range<usize>> {
let mut b = [0; 4];
let substr = substr.encode_utf8(&mut b);
self.find_slice(&*substr)
}
}

impl<'i> FindSlice<(char,)> for &'i [u8] {
#[inline(always)]
fn find_slice(&self, substr: (char,)) -> Option<crate::lib::std::ops::Range<usize>> {
let mut b = [0; 4];
let substr0 = substr.0.encode_utf8(&mut b);
self.find_slice((&*substr0,))
}
}

impl<'i> FindSlice<(char, char)> for &'i [u8] {
#[inline(always)]
fn find_slice(&self, substr: (char, char)) -> Option<crate::lib::std::ops::Range<usize>> {
let mut b = [0; 4];
let substr0 = substr.0.encode_utf8(&mut b);
let mut b = [0; 4];
let substr1 = substr.1.encode_utf8(&mut b);
self.find_slice((&*substr0, &*substr1))
}
}

impl<'i> FindSlice<(char, char, char)> for &'i [u8] {
#[inline(always)]
fn find_slice(&self, substr: (char, char, char)) -> Option<crate::lib::std::ops::Range<usize>> {
let mut b = [0; 4];
let substr0 = substr.0.encode_utf8(&mut b);
let mut b = [0; 4];
let substr1 = substr.1.encode_utf8(&mut b);
let mut b = [0; 4];
let substr2 = substr.2.encode_utf8(&mut b);
self.find_slice((&*substr0, &*substr1, &*substr2))
}
}

impl<'i> FindSlice<u8> for &'i [u8] {
#[inline(always)]
fn find_slice(&self, substr: u8) -> Option<crate::lib::std::ops::Range<usize>> {
Expand Down Expand Up @@ -2409,7 +2423,7 @@ impl<'i, 's> FindSlice<(&'s str, &'s str, &'s str)> for &'i [u8] {
impl<'i, 's> FindSlice<&'s str> for &'i str {
#[inline(always)]
fn find_slice(&self, substr: &'s str) -> Option<crate::lib::std::ops::Range<usize>> {
self.as_bytes().find_slice(substr.as_bytes())
self.as_bytes().find_slice(substr)
}
}

Expand Down Expand Up @@ -2440,70 +2454,28 @@ impl<'i, 's> FindSlice<(&'s str, &'s str, &'s str)> for &'i str {
impl<'i> FindSlice<char> for &'i str {
#[inline(always)]
fn find_slice(&self, substr: char) -> Option<crate::lib::std::ops::Range<usize>> {
let mut b = [0; 4];
let substr = substr.encode_utf8(&mut b);
self.find_slice(&*substr)
self.as_bytes().find_slice(substr)
}
}

impl<'i> FindSlice<(char,)> for &'i str {
#[inline(always)]
fn find_slice(&self, substr: (char,)) -> Option<crate::lib::std::ops::Range<usize>> {
let mut b = [0; 4];
let substr0 = substr.0.encode_utf8(&mut b);
self.find_slice((&*substr0,))
self.as_bytes().find_slice(substr)
}
}

impl<'i> FindSlice<(char, char)> for &'i str {
#[inline(always)]
fn find_slice(&self, substr: (char, char)) -> Option<crate::lib::std::ops::Range<usize>> {
let mut b = [0; 4];
let substr0 = substr.0.encode_utf8(&mut b);
let mut b = [0; 4];
let substr1 = substr.1.encode_utf8(&mut b);
self.find_slice((&*substr0, &*substr1))
self.as_bytes().find_slice(substr)
}
}

impl<'i> FindSlice<(char, char, char)> for &'i str {
#[inline(always)]
fn find_slice(&self, substr: (char, char, char)) -> Option<crate::lib::std::ops::Range<usize>> {
let mut b = [0; 4];
let substr0 = substr.0.encode_utf8(&mut b);
let mut b = [0; 4];
let substr1 = substr.1.encode_utf8(&mut b);
let mut b = [0; 4];
let substr2 = substr.2.encode_utf8(&mut b);
self.find_slice((&*substr0, &*substr1, &*substr2))
}
}

impl<'i> FindSlice<u8> for &'i str {
#[inline(always)]
fn find_slice(&self, substr: u8) -> Option<crate::lib::std::ops::Range<usize>> {
self.find_slice(substr.as_char())
}
}

impl<'i> FindSlice<(u8,)> for &'i str {
#[inline(always)]
fn find_slice(&self, substr: (u8,)) -> Option<crate::lib::std::ops::Range<usize>> {
self.find_slice((substr.0.as_char(),))
}
}

impl<'i> FindSlice<(u8, u8)> for &'i str {
#[inline(always)]
fn find_slice(&self, substr: (u8, u8)) -> Option<crate::lib::std::ops::Range<usize>> {
self.find_slice((substr.0.as_char(), substr.1.as_char()))
}
}

impl<'i> FindSlice<(u8, u8, u8)> for &'i str {
#[inline(always)]
fn find_slice(&self, substr: (u8, u8, u8)) -> Option<crate::lib::std::ops::Range<usize>> {
self.find_slice((substr.0.as_char(), substr.1.as_char(), substr.2.as_char()))
self.as_bytes().find_slice(substr)
}
}

Expand Down

0 comments on commit 46c77dc

Please sign in to comment.