From 03c6e74ac65f50e981b20e7411179e002595e53d Mon Sep 17 00:00:00 2001 From: Sean McArthur Date: Mon, 13 Nov 2023 09:54:44 -0500 Subject: [PATCH] fix MIRI error in header::Iter (#642) --- src/header/map.rs | 55 ++++++++++++++++++++++++++++++++-------- tests/header_map_fuzz.rs | 1 + 2 files changed, 45 insertions(+), 11 deletions(-) diff --git a/src/header/map.rs b/src/header/map.rs index dd0f262a..0290160e 100644 --- a/src/header/map.rs +++ b/src/header/map.rs @@ -82,7 +82,9 @@ pub struct HeaderMap { /// more than once if it has more than one associated value. #[derive(Debug)] pub struct Iter<'a, T> { - inner: IterMut<'a, T>, + map: &'a HeaderMap, + entry: usize, + cursor: Option, } /// `HeaderMap` mutable entry iterator @@ -811,12 +813,9 @@ impl HeaderMap { /// ``` pub fn iter(&self) -> Iter<'_, T> { Iter { - inner: IterMut { - map: self as *const _ as *mut _, - entry: 0, - cursor: self.entries.first().map(|_| Cursor::Head), - lt: PhantomData, - }, + map: self, + entry: 0, + cursor: self.entries.first().map(|_| Cursor::Head), } } @@ -2078,13 +2077,47 @@ impl<'a, T> Iterator for Iter<'a, T> { type Item = (&'a HeaderName, &'a T); fn next(&mut self) -> Option { - self.inner - .next_unsafe() - .map(|(key, ptr)| (key, unsafe { &*ptr })) + use self::Cursor::*; + + if self.cursor.is_none() { + if (self.entry + 1) >= self.map.entries.len() { + return None; + } + + self.entry += 1; + self.cursor = Some(Cursor::Head); + } + + let entry = &self.map.entries[self.entry]; + + match self.cursor.unwrap() { + Head => { + self.cursor = entry.links.map(|l| Values(l.next)); + Some((&entry.key, &entry.value)) + } + Values(idx) => { + let extra = &self.map.extra_values[idx]; + + match extra.next { + Link::Entry(_) => self.cursor = None, + Link::Extra(i) => self.cursor = Some(Values(i)), + } + + Some((&entry.key, &extra.value)) + } + } } fn size_hint(&self) -> (usize, Option) { - self.inner.size_hint() + let map = self.map; + debug_assert!(map.entries.len() >= self.entry); + + let lower = map.entries.len() - self.entry; + // We could pessimistically guess at the upper bound, saying + // that its lower + map.extra_values.len(). That could be + // way over though, such as if we're near the end, and have + // already gone through several extra values... + (lower, None) } } diff --git a/tests/header_map_fuzz.rs b/tests/header_map_fuzz.rs index 68a8604f..c3af2e52 100644 --- a/tests/header_map_fuzz.rs +++ b/tests/header_map_fuzz.rs @@ -8,6 +8,7 @@ use rand::{Rng, SeedableRng}; use std::collections::HashMap; +#[cfg(not(miri))] #[test] fn header_map_fuzz() { fn prop(fuzz: Fuzz) -> TestResult {