Repository: rust-bakery/nom (language: rust)

Issue:
`count` panics when parser returns zero-sized `()`
## Prerequisites

- Rust version : `rustc 1.66.0 (69f9c33d7 2022-12-12)`
- nom version : 7.1.2
- nom compilation features used: default (std)

## Test case

Example test case [(Playground)](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=d67b1d4f394814329a842fde81f9fe67):

```
use nom::{combinator::map, bytes::complete::tag, error::Error, multi::count};

fn main() {
    let parser = map(tag::<_, _, Error<&str>>("abc"), |_| ());
    let result = count(parser, 3)("abcabcabcdef").expect("parsing should succeed");
    println!("{:?}", result);
}
```

Expected: Runs fine, prints:

```
("def", [(), (), ()])
```

Result:

```
Compiling playground v0.0.1 (/playground)
    Finished dev [unoptimized + debuginfo] target(s) in 0.99s
     Running `target/debug/playground`
thread 'main' panicked at 'attempt to divide by zero', /playground/.cargo/registry/src/github.com-1ecc6299db9ec823/nom-7.1.2/src/multi/mod.rs:576:32
note: [run with `RUST_BACKTRACE=1` environment variable to display a backtrace](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=0487bcd80ada6e9943cd7b41b3dcdcbb#)
```



Discussion / hints:

Fix patch:
diff --git a/src/multi/mod.rs b/src/multi/mod.rs
index ab068c78c..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::<O>();
+    let max_initial_capacity =
+      MAX_INITIAL_CAPACITY_BYTES / crate::lib::std::mem::size_of::<O>().max(1);
     let mut res = crate::lib::std::vec::Vec::with_capacity(count.min(max_initial_capacity));
 
     for _ in 0..count {


Test patch:
diff --git a/tests/issues.rs b/tests/issues.rs
index eca53b583..8728e9dfb 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::{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![(), (), ()]));
+}