From 760f11126b63604b91d1e1df445eff86ae6ffd2a Mon Sep 17 00:00:00 2001 From: Sean McArthur Date: Mon, 13 Nov 2023 09:54:44 -0500 Subject: [PATCH 1/2] 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 { From 7f09a2193a3e4b5c752643ff04b5f728535f466a Mon Sep 17 00:00:00 2001 From: Sean McArthur Date: Mon, 13 Nov 2023 09:57:43 -0500 Subject: [PATCH 2/2] v0.2.11 --- CHANGELOG.md | 4 ++++ Cargo.toml | 2 +- src/lib.rs | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3de372b8..62fd3ebe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# 0.2.11 (November 13, 2023) + +* Fix MIRI error in `header::Iter`. + # 0.2.10 (November 10, 2023) * Fix parsing of `Authority` to handle square brackets in incorrect order. diff --git a/Cargo.toml b/Cargo.toml index 3672249b..25ca5011 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,7 +4,7 @@ name = "http" # - Update html_root_url in lib.rs. # - Update CHANGELOG.md. # - Create git tag -version = "0.2.10" +version = "0.2.11" readme = "README.md" documentation = "https://docs.rs/http" repository = "https://github.com/hyperium/http" diff --git a/src/lib.rs b/src/lib.rs index 22901438..ed570e1f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,4 +1,4 @@ -#![doc(html_root_url = "https://docs.rs/http/0.2.10")] +#![doc(html_root_url = "https://docs.rs/http/0.2.11")] //! A general purpose library of common HTTP types //!