diff --git a/.github/workflows/codspeed.yml b/.github/workflows/codspeed.yml new file mode 100644 index 000000000..ee20f6a41 --- /dev/null +++ b/.github/workflows/codspeed.yml @@ -0,0 +1,32 @@ +name: codspeed-benchmarks + +on: + push: + branches: + - "main" + pull_request: + # `workflow_dispatch` allows CodSpeed to trigger backtest + # performance analysis in order to generate initial data. + workflow_dispatch: + +jobs: + benchmarks: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + + - name: Setup rust toolchain, cache and cargo-codspeed binary + uses: moonrepo/setup-rust@v0 + with: + channel: stable + cache-target: release + bins: cargo-codspeed + + - name: Build the benchmark target(s) + run: cargo codspeed build -p benchmarks + + - name: Run the benchmarks + uses: CodSpeedHQ/action@v3 + with: + run: cargo codspeed run -p benchmarks + token: ${{ secrets.CODSPEED_TOKEN }} diff --git a/CHANGELOG.md b/CHANGELOG.md index fc94c29d5..a8f4c02c2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,16 @@ ### Changed +## 7.1.3 - 2023-01-15 + +### Thanks + +- @Shadow53 + +### Fixed + +- panic in `many` and `count` combinators when the output type is zero sized + ## 7.1.2 - 2023-01-01 ### Thanks @@ -1475,7 +1485,8 @@ Considering the number of changes since the last release, this version can conta ## Compare code -* [unreleased](https://github.com/Geal/nom/compare/7.1.2...HEAD) +* [unreleased](https://github.com/Geal/nom/compare/7.1.3...HEAD) +* [7.1.2](https://github.com/Geal/nom/compare/7.1.2...7.1.3) * [7.1.2](https://github.com/Geal/nom/compare/7.1.1...7.1.2) * [7.1.1](https://github.com/Geal/nom/compare/7.1.0...7.1.1) * [7.1.0](https://github.com/Geal/nom/compare/7.0.0...7.1.0) diff --git a/Cargo.toml b/Cargo.toml index c244efbfb..b2d72b610 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "nom" -version = "7.1.2" +version = "7.1.4-test" authors = [ "contact@geoffroycouprie.com" ] description = "A byte-oriented, zero-copy, parser combinators library" license = "MIT" diff --git a/src/multi/mod.rs b/src/multi/mod.rs index dff28e60f..73129084e 100644 --- a/src/multi/mod.rs +++ b/src/multi/mod.rs @@ -392,7 +392,8 @@ where return Err(Err::Failure(E::from_error_kind(input, ErrorKind::ManyMN))); } - 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(min.min(max_initial_capacity)); for count in 0..max { let len = input.input_len(); @@ -573,7 +574,8 @@ 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 4f7eaad18..7985702f6 100644 --- a/tests/issues.rs +++ b/tests/issues.rs @@ -229,3 +229,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![(), (), ()])); +}