diff --git a/src/header/map.rs b/src/header/map.rs index 07b4554a..ebbc5937 100644 --- a/src/header/map.rs +++ b/src/header/map.rs @@ -707,20 +707,22 @@ impl HeaderMap { .checked_add(additional) .ok_or_else(MaxSizeReached::new)?; - if cap > self.indices.len() { - let cap = cap + let raw_cap = to_raw_capacity(cap); + + if raw_cap > self.indices.len() { + let raw_cap = raw_cap .checked_next_power_of_two() .ok_or_else(MaxSizeReached::new)?; - if cap > MAX_SIZE { + if raw_cap > MAX_SIZE { return Err(MaxSizeReached::new()); } if self.entries.is_empty() { - self.mask = cap as Size - 1; - self.indices = vec![Pos::none(); cap].into_boxed_slice(); - self.entries = Vec::with_capacity(usable_capacity(cap)); + self.mask = raw_cap as Size - 1; + self.indices = vec![Pos::none(); raw_cap].into_boxed_slice(); + self.entries = Vec::with_capacity(usable_capacity(raw_cap)); } else { - self.try_grow(cap)?; + self.try_grow(raw_cap)?; } } diff --git a/tests/header_map.rs b/tests/header_map.rs index 9859b0a8..9a9d7e12 100644 --- a/tests/header_map.rs +++ b/tests/header_map.rs @@ -63,6 +63,30 @@ fn reserve_overflow() { headers.reserve(std::usize::MAX); // next_power_of_two overflows } +#[test] +fn reserve() { + let mut headers = HeaderMap::::default(); + assert_eq!(headers.capacity(), 0); + + let requested_cap = 8; + headers.reserve(requested_cap); + + let reserved_cap = headers.capacity(); + assert!( + reserved_cap >= requested_cap, + "requested {} capacity, but it reserved only {} entries", + requested_cap, + reserved_cap, + ); + + for i in 0..requested_cap { + let name = format!("h{i}").parse::().unwrap(); + headers.insert(name, i); + } + + assert_eq!(headers.capacity(), reserved_cap, "unexpected reallocation"); +} + #[test] fn drain() { let mut headers = HeaderMap::new();