Skip to content

Commit 2371914

Browse files
committed
Prevent Zip specialization from calling __iterator_get_unchecked twice with the same index after calling next_back
1 parent 8fd946c commit 2371914

File tree

1 file changed

+9
-4
lines changed
  • library/core/src/iter/adapters

1 file changed

+9
-4
lines changed

library/core/src/iter/adapters/zip.rs

+9-4
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,10 @@ use crate::iter::{InPlaceIterable, SourceIter, TrustedLen};
1313
pub struct Zip<A, B> {
1414
a: A,
1515
b: B,
16-
// index and len are only used by the specialized version of zip
16+
// index, len and a_len are only used by the specialized version of zip
1717
index: usize,
1818
len: usize,
19+
a_len: usize,
1920
}
2021
impl<A: Iterator, B: Iterator> Zip<A, B> {
2122
pub(in crate::iter) fn new(a: A, b: B) -> Zip<A, B> {
@@ -110,6 +111,7 @@ where
110111
b,
111112
index: 0, // unused
112113
len: 0, // unused
114+
a_len: 0, // unused
113115
}
114116
}
115117

@@ -184,8 +186,9 @@ where
184186
B: TrustedRandomAccess + Iterator,
185187
{
186188
fn new(a: A, b: B) -> Self {
187-
let len = cmp::min(a.size(), b.size());
188-
Zip { a, b, index: 0, len }
189+
let a_len = a.size();
190+
let len = cmp::min(a_len, b.size());
191+
Zip { a, b, index: 0, len, a_len }
189192
}
190193

191194
#[inline]
@@ -197,7 +200,7 @@ where
197200
unsafe {
198201
Some((self.a.__iterator_get_unchecked(i), self.b.__iterator_get_unchecked(i)))
199202
}
200-
} else if A::MAY_HAVE_SIDE_EFFECT && self.index < self.a.size() {
203+
} else if A::MAY_HAVE_SIDE_EFFECT && self.index < self.a_len {
201204
let i = self.index;
202205
self.index += 1;
203206
self.len += 1;
@@ -262,6 +265,7 @@ where
262265
for _ in 0..sz_a - self.len {
263266
self.a.next_back();
264267
}
268+
self.a_len = self.len;
265269
}
266270
let sz_b = self.b.size();
267271
if B::MAY_HAVE_SIDE_EFFECT && sz_b > self.len {
@@ -273,6 +277,7 @@ where
273277
}
274278
if self.index < self.len {
275279
self.len -= 1;
280+
self.a_len -= 1;
276281
let i = self.len;
277282
// SAFETY: `i` is smaller than the previous value of `self.len`,
278283
// which is also smaller than or equal to `self.a.len()` and `self.b.len()`

0 commit comments

Comments
 (0)