Skip to content

Commit

Permalink
move the loop check of separated list to cover both parsers
Browse files Browse the repository at this point in the history
  • Loading branch information
Geal committed May 5, 2024
1 parent 83cfb17 commit c4a6f52
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 19 deletions.
29 changes: 15 additions & 14 deletions src/multi/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -420,13 +420,6 @@ where
Err(Err::Failure(e)) => return Err(Err::Failure(e)),
Err(Err::Incomplete(e)) => return Err(Err::Incomplete(e)),
Ok((i1, _)) => {
// infinite loop check: the parser must always consume
if i1.input_len() == len {
return Err(Err::Error(OM::Error::bind(|| {
<F as Parser<I>>::Error::from_error_kind(i, ErrorKind::SeparatedList)
})));
}

match self
.parser
.process::<OutputM<OM::Output, Check, OM::Incomplete>>(i1.clone())
Expand All @@ -435,10 +428,18 @@ where
Err(Err::Failure(e)) => return Err(Err::Failure(e)),
Err(Err::Incomplete(e)) => return Err(Err::Incomplete(e)),
Ok((i2, o)) => {
// infinite loop check: the parser must always consume
if i2.input_len() == len {
return Err(Err::Error(OM::Error::bind(|| {
<F as Parser<I>>::Error::from_error_kind(i, ErrorKind::SeparatedList)
})));
}

res = OM::Output::combine(res, o, |mut res, o| {
res.push(o);
res
});

i = i2;
}
}
Expand Down Expand Up @@ -532,13 +533,6 @@ where
Err(Err::Failure(e)) => return Err(Err::Failure(e)),
Err(Err::Incomplete(e)) => return Err(Err::Incomplete(e)),
Ok((i1, _)) => {
// infinite loop check: the parser must always consume
if i1.input_len() == len {
return Err(Err::Error(OM::Error::bind(|| {
<F as Parser<I>>::Error::from_error_kind(i, ErrorKind::SeparatedList)
})));
}

match self
.parser
.process::<OutputM<OM::Output, Check, OM::Incomplete>>(i1.clone())
Expand All @@ -547,6 +541,13 @@ where
Err(Err::Failure(e)) => return Err(Err::Failure(e)),
Err(Err::Incomplete(e)) => return Err(Err::Incomplete(e)),
Ok((i2, o)) => {
// infinite loop check: the parser must always consume
if i2.input_len() == len {
return Err(Err::Error(OM::Error::bind(|| {
<F as Parser<I>>::Error::from_error_kind(i, ErrorKind::SeparatedList)

Check warning on line 547 in src/multi/mod.rs

View check run for this annotation

Codecov / codecov/patch

src/multi/mod.rs#L546-L547

Added lines #L546 - L547 were not covered by tests
})));
}

res = OM::Output::combine(res, o, |mut res, o| {
res.push(o);
res
Expand Down
16 changes: 11 additions & 5 deletions src/multi/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ use crate::{
#[test]
#[cfg(feature = "alloc")]
fn separated_list0_test() {
use core::num::NonZeroUsize;

fn multi(i: &[u8]) -> IResult<&[u8], Vec<&[u8]>> {
separated_list0(tag(","), tag("abcd")).parse(i)
}
Expand All @@ -33,6 +35,9 @@ fn separated_list0_test() {
fn multi_longsep(i: &[u8]) -> IResult<&[u8], Vec<&[u8]>> {
separated_list0(tag(".."), tag("abcd")).parse(i)
}
fn empty_both(i: &[u8]) -> IResult<&[u8], Vec<&[u8]>> {
separated_list0(tag(""), tag("")).parse(i)
}

let a = &b"abcdef"[..];
let b = &b"abcd,abcdef"[..];
Expand All @@ -51,13 +56,14 @@ fn separated_list0_test() {
assert_eq!(multi(c), Ok((&b"azerty"[..], Vec::new())));
let res3 = vec![&b""[..], &b""[..], &b""[..]];
assert_eq!(multi_empty(d), Ok((&b"abc"[..], res3)));
let i_err_pos = &i[3..];
assert_eq!(
empty_sep(i),
Err(Err::Error(error_position!(
i_err_pos,
ErrorKind::SeparatedList
)))
Err(Err::Incomplete(Needed::Size(NonZeroUsize::new(3).unwrap())))
);

assert_eq!(
empty_both(i),
Err(Err::Error(error_position!(i, ErrorKind::SeparatedList)))
);
let res4 = vec![&b"abcd"[..], &b"abcd"[..]];
assert_eq!(multi(e), Ok((&b",ef"[..], res4)));
Expand Down

0 comments on commit c4a6f52

Please sign in to comment.