Skip to content

Commit 03c6e74

Browse files
committed
fix MIRI error in header::Iter (#642)
1 parent 818269d commit 03c6e74

File tree

2 files changed

+45
-11
lines changed

2 files changed

+45
-11
lines changed

src/header/map.rs

+44-11
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,9 @@ pub struct HeaderMap<T = HeaderValue> {
8282
/// more than once if it has more than one associated value.
8383
#[derive(Debug)]
8484
pub struct Iter<'a, T> {
85-
inner: IterMut<'a, T>,
85+
map: &'a HeaderMap<T>,
86+
entry: usize,
87+
cursor: Option<Cursor>,
8688
}
8789

8890
/// `HeaderMap` mutable entry iterator
@@ -811,12 +813,9 @@ impl<T> HeaderMap<T> {
811813
/// ```
812814
pub fn iter(&self) -> Iter<'_, T> {
813815
Iter {
814-
inner: IterMut {
815-
map: self as *const _ as *mut _,
816-
entry: 0,
817-
cursor: self.entries.first().map(|_| Cursor::Head),
818-
lt: PhantomData,
819-
},
816+
map: self,
817+
entry: 0,
818+
cursor: self.entries.first().map(|_| Cursor::Head),
820819
}
821820
}
822821

@@ -2078,13 +2077,47 @@ impl<'a, T> Iterator for Iter<'a, T> {
20782077
type Item = (&'a HeaderName, &'a T);
20792078

20802079
fn next(&mut self) -> Option<Self::Item> {
2081-
self.inner
2082-
.next_unsafe()
2083-
.map(|(key, ptr)| (key, unsafe { &*ptr }))
2080+
use self::Cursor::*;
2081+
2082+
if self.cursor.is_none() {
2083+
if (self.entry + 1) >= self.map.entries.len() {
2084+
return None;
2085+
}
2086+
2087+
self.entry += 1;
2088+
self.cursor = Some(Cursor::Head);
2089+
}
2090+
2091+
let entry = &self.map.entries[self.entry];
2092+
2093+
match self.cursor.unwrap() {
2094+
Head => {
2095+
self.cursor = entry.links.map(|l| Values(l.next));
2096+
Some((&entry.key, &entry.value))
2097+
}
2098+
Values(idx) => {
2099+
let extra = &self.map.extra_values[idx];
2100+
2101+
match extra.next {
2102+
Link::Entry(_) => self.cursor = None,
2103+
Link::Extra(i) => self.cursor = Some(Values(i)),
2104+
}
2105+
2106+
Some((&entry.key, &extra.value))
2107+
}
2108+
}
20842109
}
20852110

20862111
fn size_hint(&self) -> (usize, Option<usize>) {
2087-
self.inner.size_hint()
2112+
let map = self.map;
2113+
debug_assert!(map.entries.len() >= self.entry);
2114+
2115+
let lower = map.entries.len() - self.entry;
2116+
// We could pessimistically guess at the upper bound, saying
2117+
// that its lower + map.extra_values.len(). That could be
2118+
// way over though, such as if we're near the end, and have
2119+
// already gone through several extra values...
2120+
(lower, None)
20882121
}
20892122
}
20902123

tests/header_map_fuzz.rs

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use rand::{Rng, SeedableRng};
88

99
use std::collections::HashMap;
1010

11+
#[cfg(not(miri))]
1112
#[test]
1213
fn header_map_fuzz() {
1314
fn prop(fuzz: Fuzz) -> TestResult {

0 commit comments

Comments
 (0)