diff options
| author | Tyler Mandry <tmandry@gmail.com> | 2020-01-24 00:30:56 -0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-01-24 00:30:56 -0800 |
| commit | e7752aefdc0765f9350cbe5d563d6f46f9045e26 (patch) | |
| tree | 1ac0f937d02fcd94986e94400f70d13324c7ea25 | |
| parent | 143059deafe1e5df3cbbaf4d47f5461af7bcf8c3 (diff) | |
| parent | 9d3e84432dae2e96a5e0f97be18ee09b5a2217b1 (diff) | |
| download | rust-e7752aefdc0765f9350cbe5d563d6f46f9045e26.tar.gz rust-e7752aefdc0765f9350cbe5d563d6f46f9045e26.zip | |
Rollup merge of #68469 - ollie27:skip_count, r=sfackler
Avoid overflow in `std::iter::Skip::count` The call to `count` on the inner iterator can overflow even if `Skip` itself would return less that `usize::max_value()` items. Fixes #68139
| -rw-r--r-- | src/libcore/iter/adapters/mod.rs | 10 | ||||
| -rw-r--r-- | src/test/ui/iterators/skip-count-overflow.rs | 8 |
2 files changed, 16 insertions, 2 deletions
diff --git a/src/libcore/iter/adapters/mod.rs b/src/libcore/iter/adapters/mod.rs index 6eb837ed0fe..5787b9174ed 100644 --- a/src/libcore/iter/adapters/mod.rs +++ b/src/libcore/iter/adapters/mod.rs @@ -1815,8 +1815,14 @@ where } #[inline] - fn count(self) -> usize { - self.iter.count().saturating_sub(self.n) + fn count(mut self) -> usize { + if self.n > 0 { + // nth(n) skips n+1 + if self.iter.nth(self.n - 1).is_none() { + return 0; + } + } + self.iter.count() } #[inline] diff --git a/src/test/ui/iterators/skip-count-overflow.rs b/src/test/ui/iterators/skip-count-overflow.rs new file mode 100644 index 00000000000..d8efc948664 --- /dev/null +++ b/src/test/ui/iterators/skip-count-overflow.rs @@ -0,0 +1,8 @@ +// run-pass +// only-32bit too impatient for 2⁶⁴ items +// compile-flags: -C overflow-checks -C opt-level=3 + +fn main() { + let i = (0..usize::max_value()).chain(0..10).skip(usize::max_value()); + assert_eq!(i.count(), 10); +} |
