From 0cce53c1436e9c18a997080a28a3a97d624668c4 Mon Sep 17 00:00:00 2001
From: "Herman J. Radtke III" <herman@hermanradtke.com>
Date: Sun, 12 Nov 2023 18:53:44 -0500
Subject: [PATCH 1/3] chore(ci): run miri tests

---
 .github/workflows/ci.yml | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 13c79504..6049236e 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -79,3 +79,19 @@ jobs:
 
       - name: Check
         run: cargo check --target wasm32-unknown-unknown
+
+  miri:
+    name: Miri
+    runs-on: ubuntu-latest
+
+    steps:
+      - name: Checkout
+        uses: actions/checkout@v3
+
+      - name: Install Rust
+        uses: dtolnay/rust-toolchain@nightly
+        with:
+          components: miri
+
+      - name: Test
+        run: MIRIFLAGS="-Zmiri-disable-isolation -Zmiri-ignore-leaks" cargo miri test

From 03629a303ad9d24e1a9f27e4b1d02c5b961acb0c Mon Sep 17 00:00:00 2001
From: "Herman J. Radtke III" <herman@hermanradtke.com>
Date: Sun, 12 Nov 2023 18:54:45 -0500
Subject: [PATCH 2/3] revert: make miri happy

This reverts commit 78e3d37563b0fe83886abffdcd8569117d45fee9.
---
 src/header/map.rs | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/src/header/map.rs b/src/header/map.rs
index dd0f262a..1ea2cf5c 100644
--- a/src/header/map.rs
+++ b/src/header/map.rs
@@ -2108,22 +2108,22 @@ impl<'a, T> IterMut<'a, T> {
             self.cursor = Some(Cursor::Head);
         }
 
-        let entry = unsafe { &mut (*self.map).entries[self.entry] };
+        let entry = unsafe { &(*self.map).entries[self.entry] };
 
         match self.cursor.unwrap() {
             Head => {
                 self.cursor = entry.links.map(|l| Values(l.next));
-                Some((&entry.key, &mut entry.value as *mut _))
+                Some((&entry.key, &entry.value as *const _ as *mut _))
             }
             Values(idx) => {
-                let extra = unsafe { &mut (*self.map).extra_values[idx] };
+                let extra = unsafe { &(*self.map).extra_values[idx] };
 
                 match extra.next {
                     Link::Entry(_) => self.cursor = None,
                     Link::Extra(i) => self.cursor = Some(Values(i)),
                 }
 
-                Some((&entry.key, &mut extra.value as *mut _))
+                Some((&entry.key, &extra.value as *const _ as *mut _))
             }
         }
     }

From 0a8c4e140d6121cc60d485b61bfbccdcd9d38b8e Mon Sep 17 00:00:00 2001
From: "Herman J. Radtke III" <herman@hermanradtke.com>
Date: Sun, 12 Nov 2023 18:59:44 -0500
Subject: [PATCH 3/3] test: add test to ensure HeaderMap::iter safety

---
 tests/header_map.rs | 20 ++++++++++++++++----
 1 file changed, 16 insertions(+), 4 deletions(-)

diff --git a/tests/header_map.rs b/tests/header_map.rs
index f2beba08..9859b0a8 100644
--- a/tests/header_map.rs
+++ b/tests/header_map.rs
@@ -190,7 +190,7 @@ fn drain_entry() {
         assert_eq!(vals[1], "world2");
     }
 
-    assert_eq!(5-2+1, headers.len());
+    assert_eq!(5 - 2 + 1, headers.len());
 }
 
 #[test]
@@ -427,7 +427,6 @@ fn value_htab() {
     HeaderValue::from_str("hello\tworld").unwrap();
 }
 
-
 #[test]
 fn remove_multiple_a() {
     let mut headers = HeaderMap::new();
@@ -570,7 +569,8 @@ fn remove_entry_multi_3_others() {
 }
 
 fn remove_all_values<K>(headers: &mut HeaderMap, key: K) -> Vec<HeaderValue>
-    where K: IntoHeaderName
+where
+    K: IntoHeaderName,
 {
     match headers.entry(key) {
         Entry::Occupied(e) => e.remove_entry_mult().1.collect(),
@@ -629,10 +629,22 @@ fn remove_entry_3_others_b() {
 }
 
 fn remove_values<K>(headers: &mut HeaderMap, key: K) -> Option<HeaderValue>
-    where K: IntoHeaderName
+where
+    K: IntoHeaderName,
 {
     match headers.entry(key) {
         Entry::Occupied(e) => Some(e.remove_entry().1),
         Entry::Vacant(_) => None,
     }
 }
+
+#[test]
+fn ensure_miri_sharedreadonly_not_violated() {
+    let mut headers = HeaderMap::new();
+    headers.insert(
+        HeaderName::from_static("chunky-trailer"),
+        HeaderValue::from_static("header data"),
+    );
+
+    let _foo = &headers.iter().next();
+}