Skip to content

Commit

Permalink
Fix overflow when initializing a Sieve with T::MAX (#47)
Browse files Browse the repository at this point in the history
  • Loading branch information
dvdplm authored Oct 9, 2024
1 parent e1bd96d commit 35ccd95
Showing 1 changed file with 17 additions and 12 deletions.
29 changes: 17 additions & 12 deletions src/hazmat/sieve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ impl<T: Integer> Sieve<T> {
self.base = self
.base
.checked_add(&self.incr.into())
.expect("addition should not overflow by construction");
.expect("Does not overflow by construction");

self.incr = 0;

Expand Down Expand Up @@ -205,17 +205,16 @@ impl<T: Integer> Sieve<T> {
let result = if self.current_is_composite() {
None
} else {
// The overflow should never happen here since `incr`
// is never greater than `incr_limit`, and the latter is chosen such that
// it does not overflow when added to `base` (see `update_residues()`).
let mut num = self
.base
.checked_add(&self.incr.into())
.expect("addition should not overflow by construction");
if self.safe_primes {
num = num.wrapping_shl_vartime(1) | T::one_like(&self.base);
match self.base.checked_add(&self.incr.into()).into_option() {
Some(mut num) => {
if self.safe_primes {
// Divide by 2 and ensure it's odd with an OR.
num = num.wrapping_shl_vartime(1) | T::one_like(&self.base);
}
Some(num)
}
None => None,
}
Some(num)
};

self.incr += 2;
Expand All @@ -224,7 +223,6 @@ impl<T: Integer> Sieve<T> {

fn next(&mut self) -> Option<T> {
// Corner cases handled here

if self.produces_nothing {
return None;
}
Expand Down Expand Up @@ -403,4 +401,11 @@ mod tests {
let s3 = Sieve::new(U64::ONE, NonZeroU32::new(12).unwrap(), false);
assert_ne!(s, s3);
}

#[test]
fn sieve_with_max_start() {
let start = U64::MAX;
let mut sieve = Sieve::new(&start, NonZeroU32::new(U64::BITS).unwrap(), false);
assert!(sieve.next().is_none());
}
}

0 comments on commit 35ccd95

Please sign in to comment.