From 949ab4a4d31a0f0c4ad9f870c634c8f462c18637 Mon Sep 17 00:00:00 2001 From: gngpp Date: Fri, 7 Aug 2026 10:15:40 +0800 Subject: [PATCH] fix(qpack): reject invalid negative delta base --- http3/src/qpack/block.rs | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/http3/src/qpack/block.rs b/http3/src/qpack/block.rs index 6ee2922..533825e 100644 --- a/http3/src/qpack/block.rs +++ b/http3/src/qpack/block.rs @@ -181,13 +181,14 @@ impl HeaderPrefix { // Delta Base is peer-controlled. Checked arithmetic rejects a Base that // cannot be represented as `usize`. // https://www.rfc-editor.org/rfc/rfc9204.html#section-4.5.1 - let base = if required == 0 { - 0 - } else if !self.sign_negative { + let base = if !self.sign_negative { required .checked_add(self.delta_base) .ok_or_else(invalid_base)? } else { + // A negative sign is invalid when Required Insert Count is no + // greater than Delta Base, including when both values are zero. + // https://www.rfc-editor.org/rfc/rfc9204.html#section-4.5.1.2 required .checked_sub(self.delta_base) .and_then(|base| base.checked_sub(1)) @@ -575,6 +576,24 @@ mod test { ); } + #[test] + fn negative_delta_base_with_zero_required_insert_count_is_rejected() { + let prefix = HeaderPrefix { + encoded_insert_count: 0, + sign_negative: true, + delta_base: 0, + }; + + assert_eq!( + prefix.get(0, TABLE_SIZE), + Err(ParseError::InvalidBase { + required_insert_count: 0, + sign_negative: true, + delta_base: 0, + }) + ); + } + #[test] fn positive_delta_base_overflow_is_rejected() { let mut field_section = vec![];