Skip to content

Commit 006a742

Browse files
Fix some IncBy constructor overflow edge cases reported on Reddit
1 parent fb26f9e commit 006a742

File tree

3 files changed

+20
-6
lines changed

3 files changed

+20
-6
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ repository = "https://github.com/slightlyoutofphase/staticstep"
55
documentation = "https://docs.rs/staticstep/"
66
license = "MIT OR Apache-2.0"
77
readme = "README.md"
8-
version = "0.2.2"
8+
version = "0.3.0"
99
keywords = ["iterator", "iterators", "step", "range", "ranges"]
1010
categories = ["data-structures", "algorithms"]
1111
edition = "2018"

src/lib.rs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ impl<T: Copy + Default + Step, const STEP: usize> IncBy<T, STEP> {
3131
};
3232
let end = match bounds.end_bound() {
3333
Included(&idx) => Step::forward(idx, STEP),
34-
Excluded(&idx) => Step::forward(idx, STEP - 1),
34+
Excluded(&idx) => Step::forward_checked(idx, STEP - 1).unwrap_or(idx),
3535
Unbounded => Default::default(),
3636
};
3737
IncBy { start, end }
@@ -60,10 +60,14 @@ impl<T: Copy + Default + Step, const STEP: usize> Iterator for IncBy<T, STEP> {
6060

6161
#[inline(always)]
6262
fn next(&mut self) -> Option<T> {
63-
if self.start <= Step::backward(self.end, STEP) {
64-
let res = Some(self.start);
65-
self.start = Step::forward(self.start, STEP);
66-
res
63+
if let Some(end_back) = Step::backward_checked(self.end, STEP) {
64+
if self.start <= end_back {
65+
let res = Some(self.start);
66+
self.start = Step::forward(self.start, STEP);
67+
res
68+
} else {
69+
None
70+
}
6771
} else {
6872
None
6973
}

tests/test_staticstep.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,3 +236,13 @@ fn dec_by_inclusive_char_range() {
236236
assert_eq!(r.next(), Some('A'));
237237
assert_eq!(r.next(), None);
238238
}
239+
240+
#[test]
241+
fn inc_by_type_dependent_overflow() {
242+
let mut r = (248u8..255u8).inc_by::<50>();
243+
assert_eq!(r.next(), None);
244+
let mut r2 = (248u32..255u32).inc_by::<{ usize::MAX }>();
245+
assert_eq!(r2.next(), None);
246+
let mut r3 = (248i32..255i32).inc_by::<{ u32::MAX as usize }>();
247+
assert_eq!(r3.next(), None);
248+
}

0 commit comments

Comments
 (0)