diff --git a/rust/src/http2/http2.rs b/rust/src/http2/http2.rs index ecd7ea647d..284105f16a 100644 --- a/rust/src/http2/http2.rs +++ b/rust/src/http2/http2.rs @@ -1295,14 +1295,20 @@ impl HTTP2State { &mut self.c2s_buf }; buf.data.clear(); - buf.data.extend(input); - buf.stream_id = head.stream_id; - let hs = parser::HTTP2FrameHeaders { - padlength: None, - priority: None, - blocks: Vec::new(), - }; - return (HTTP2FrameTypeData::HEADERS(hs), events); + if let Ok((rem_hpack, hs)) = parser::get_frame_headers_hpack(input, hflags) { + // store only the HPACK fragment: skip Pad Length, Priority, and trailing padding + buf.data.extend(rem_hpack); + buf.stream_id = head.stream_id; + return (HTTP2FrameTypeData::HEADERS(hs), events); + } else { + events.push(HTTP2Event::InvalidFrameData); + return ( + HTTP2FrameTypeData::UNHANDLED(HTTP2FrameUnhandled { + reason: HTTP2FrameUnhandledReason::ParsingError, + }), + events, + ); + } } let dyn_headers = if dir == Direction::ToClient { &mut self.dynamic_headers_tc diff --git a/rust/src/http2/parser.rs b/rust/src/http2/parser.rs index e436bafaed..9f0d49a03c 100644 --- a/rust/src/http2/parser.rs +++ b/rust/src/http2/parser.rs @@ -591,6 +591,24 @@ fn http2_parse_headers_blocks<'a>( return Ok((i3, blocks)); } +pub(super) fn get_frame_headers_hpack( + input: &[u8], flags: u8, +) -> IResult<&[u8], HTTP2FrameHeaders> { + let (i2, padlength) = cond(flags & HTTP2_FLAG_HEADER_PADDED != 0, be_u8)(input)?; + let (i3, priority) = cond( + flags & HTTP2_FLAG_HEADER_PRIORITY != 0, + http2_parse_headers_priority, + )(i2)?; + return Ok(( + i3, + HTTP2FrameHeaders { + padlength, + priority, + blocks: Vec::new(), + }, + )); +} + pub fn http2_parse_frame_headers<'a>( input: &'a [u8], flags: u8, dyn_headers: &mut HTTP2DynTable, ) -> IResult<&'a [u8], HTTP2FrameHeaders> {