From ff07816b650997b0050811c1fd300c0da1104b59 Mon Sep 17 00:00:00 2001
From: fakeshadow <24548779@qq.com>
Date: Sun, 29 Aug 2021 08:42:22 +0800
Subject: [PATCH] update httparse for uninit header parsing (#2374)

---
 actix-http/Cargo.toml        |  2 +-
 actix-http/src/h1/decoder.rs | 15 +++++++++++----
 2 files changed, 12 insertions(+), 5 deletions(-)

diff --git a/actix-http/Cargo.toml b/actix-http/Cargo.toml
index 4ce55dca..68f98098 100644
--- a/actix-http/Cargo.toml
+++ b/actix-http/Cargo.toml
@@ -59,7 +59,7 @@ futures-core = { version = "0.3.7", default-features = false, features = ["alloc
 futures-util = { version = "0.3.7", default-features = false, features = ["alloc", "sink"] }
 h2 = "0.3.1"
 http = "0.2.2"
-httparse = "1.3"
+httparse = "1.5.1"
 itoa = "0.4"
 language-tags = "0.3"
 local-channel = "0.1"
diff --git a/actix-http/src/h1/decoder.rs b/actix-http/src/h1/decoder.rs
index 313ffd5e..91a3af44 100644
--- a/actix-http/src/h1/decoder.rs
+++ b/actix-http/src/h1/decoder.rs
@@ -1,4 +1,4 @@
-use std::{convert::TryFrom, io, marker::PhantomData, task::Poll};
+use std::{convert::TryFrom, io, marker::PhantomData, mem::MaybeUninit, task::Poll};
 
 use actix_codec::Decoder;
 use bytes::{Bytes, BytesMut};
@@ -212,10 +212,17 @@ impl MessageType for Request {
         let mut headers: [HeaderIndex; MAX_HEADERS] = EMPTY_HEADER_INDEX_ARRAY;
 
         let (len, method, uri, ver, h_len) = {
-            let mut parsed: [httparse::Header<'_>; MAX_HEADERS] = EMPTY_HEADER_ARRAY;
+            // SAFETY:
+            // Create an uninitialized array of `MaybeUninit`. The `assume_init` is
+            // safe because the type we are claiming to have initialized here is a
+            // bunch of `MaybeUninit`s, which do not require initialization.
+            let mut parsed = unsafe {
+                MaybeUninit::<[MaybeUninit<httparse::Header<'_>>; MAX_HEADERS]>::uninit()
+                    .assume_init()
+            };
 
-            let mut req = httparse::Request::new(&mut parsed);
-            match req.parse(src)? {
+            let mut req = httparse::Request::new(&mut []);
+            match req.parse_with_uninit_headers(src, &mut parsed)? {
                 httparse::Status::Complete(len) => {
                     let method = Method::from_bytes(req.method.unwrap().as_bytes())
                         .map_err(|_| ParseError::Method)?;