From 8048eb8ced2087659184f70bae9e0d91690aa212 Mon Sep 17 00:00:00 2001 From: Ragnar Groot Koerkamp Date: Wed, 9 Feb 2022 09:01:48 +0100 Subject: [PATCH] fix: overflow in `qgrams` for k=32 (#478) * Fix undefined behaviour overflow for k=32 * Add a test to RankTransform ensuring `1<<(q*bits)` does not overflow * Update MSRV to 1.53 for usize::BITS --- .github/workflows/rust.yml | 4 ++-- README.md | 2 +- src/alphabets/mod.rs | 11 ++++++++++- 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 41e1338696..fb6f2fb156 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -92,11 +92,11 @@ jobs: - name: Install MSRV toolchain uses: actions-rs/toolchain@v1 with: - toolchain: 1.51.0 + toolchain: 1.53.0 override: true - name: check if README matches MSRV defined here - run: grep '1.51.0' README.md + run: grep '1.53.0' README.md - name: Run tests uses: actions-rs/cargo@v1 diff --git a/README.md b/README.md index 2b6da77d53..e2192bd31d 100644 --- a/README.md +++ b/README.md @@ -57,7 +57,7 @@ For extra credit, feel free to familiarize yourself with: ## Minimum supported Rust version -Currently the minimum supported Rust version is 1.51.0. +Currently the minimum supported Rust version is 1.53.0. ## License diff --git a/src/alphabets/mod.rs b/src/alphabets/mod.rs index ad46bd5a3f..83b756dcde 100644 --- a/src/alphabets/mod.rs +++ b/src/alphabets/mod.rs @@ -326,7 +326,7 @@ impl RankTransform { text: text.into_iter(), ranks: self, bits, - mask: (1 << (q * bits)) - 1, + mask: 1usize.checked_shl(q * bits).unwrap_or(0).wrapping_sub(1), qgram: 0, }; @@ -448,4 +448,13 @@ mod tests { assert_eq!(Alphabet::new(b"ATCG"), Alphabet::new(b"TAGC")); assert_ne!(Alphabet::new(b"ATCG"), Alphabet::new(b"ATC")); } + + /// When `q * bits == usize::BITS`, make sure that `1<<(1*bits)` does not overflow. + #[test] + fn test_qgram_shiftleft_overflow() { + let alphabet = Alphabet::new(b"ACTG"); + let transform = RankTransform::new(&alphabet); + let text = b"ACTG".repeat(100); + transform.qgrams(usize::BITS / 2, text); + } }