From d560e8d463c1a44f48a9c958fe5f3a00a0e96a7c Mon Sep 17 00:00:00 2001 From: Michael Bryant Date: Mon, 9 Jan 2023 21:32:36 -0800 Subject: [PATCH 1/2] avoid panic when counting zero-sized outputs in count() --- src/multi/mod.rs | 2 +- tests/issues.rs | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/multi/mod.rs b/src/multi/mod.rs index ab068c78c..dd46c04d6 100644 --- a/src/multi/mod.rs +++ b/src/multi/mod.rs @@ -579,7 +579,7 @@ where { move |i: I| { let mut input = i.clone(); - let max_initial_capacity = MAX_INITIAL_CAPACITY_BYTES / crate::lib::std::mem::size_of::(); + let max_initial_capacity = MAX_INITIAL_CAPACITY_BYTES / crate::lib::std::mem::size_of::().max(1); let mut res = crate::lib::std::vec::Vec::with_capacity(count.min(max_initial_capacity)); for _ in 0..count { diff --git a/tests/issues.rs b/tests/issues.rs index eca53b583..c4f376707 100644 --- a/tests/issues.rs +++ b/tests/issues.rs @@ -242,6 +242,7 @@ fn issue_x_looser_fill_bounds() { ); } +#[test] fn issue_1459_clamp_capacity() { use nom::character::complete::char; @@ -255,3 +256,14 @@ fn issue_1459_clamp_capacity() { let mut parser = count::<_, _, (), _>(char('a'), usize::MAX); assert_eq!(parser("a"), Err(nom::Err::Error(()))); } + +#[test] +fn issue_1617_count_parser_returning_zero_size() { + use nom::{combinator::map, bytes::complete::tag, error::Error, multi::count}; + + // previously, `count()` panicked if the parser had type `O = ()` + let parser = map(tag::<_, _, Error<&str>>("abc"), |_| ()); + // shouldn't panic + let result = count(parser, 3)("abcabcabcdef").expect("parsing should succeed"); + assert_eq!(result, ("def", vec![(), (), ()])); +} From 4026657fabcbf69a9241eed2af5ea5a6578981df Mon Sep 17 00:00:00 2001 From: Michael Bryant Date: Mon, 9 Jan 2023 21:38:29 -0800 Subject: [PATCH 2/2] run cargo fmt --- src/multi/mod.rs | 3 ++- tests/issues.rs | 12 ++++++------ 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/multi/mod.rs b/src/multi/mod.rs index dd46c04d6..1b4b037ac 100644 --- a/src/multi/mod.rs +++ b/src/multi/mod.rs @@ -579,7 +579,8 @@ where { move |i: I| { let mut input = i.clone(); - let max_initial_capacity = MAX_INITIAL_CAPACITY_BYTES / crate::lib::std::mem::size_of::().max(1); + let max_initial_capacity = + MAX_INITIAL_CAPACITY_BYTES / crate::lib::std::mem::size_of::().max(1); let mut res = crate::lib::std::vec::Vec::with_capacity(count.min(max_initial_capacity)); for _ in 0..count { diff --git a/tests/issues.rs b/tests/issues.rs index c4f376707..8728e9dfb 100644 --- a/tests/issues.rs +++ b/tests/issues.rs @@ -259,11 +259,11 @@ fn issue_1459_clamp_capacity() { #[test] fn issue_1617_count_parser_returning_zero_size() { - use nom::{combinator::map, bytes::complete::tag, error::Error, multi::count}; + use nom::{bytes::complete::tag, combinator::map, error::Error, multi::count}; - // previously, `count()` panicked if the parser had type `O = ()` - let parser = map(tag::<_, _, Error<&str>>("abc"), |_| ()); - // shouldn't panic - let result = count(parser, 3)("abcabcabcdef").expect("parsing should succeed"); - assert_eq!(result, ("def", vec![(), (), ()])); + // previously, `count()` panicked if the parser had type `O = ()` + let parser = map(tag::<_, _, Error<&str>>("abc"), |_| ()); + // shouldn't panic + let result = count(parser, 3)("abcabcabcdef").expect("parsing should succeed"); + assert_eq!(result, ("def", vec![(), (), ()])); }