• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2018 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "quiche/quic/core/qpack/qpack_decoder.h"
6 
7 #include <algorithm>
8 
9 #include "absl/strings/escaping.h"
10 #include "absl/strings/string_view.h"
11 #include "quiche/quic/platform/api/quic_flags.h"
12 #include "quiche/quic/platform/api/quic_logging.h"
13 #include "quiche/quic/platform/api/quic_test.h"
14 #include "quiche/quic/test_tools/qpack/qpack_decoder_test_utils.h"
15 #include "quiche/quic/test_tools/qpack/qpack_test_utils.h"
16 
17 using ::testing::_;
18 using ::testing::Eq;
19 using ::testing::Invoke;
20 using ::testing::Mock;
21 using ::testing::Sequence;
22 using ::testing::StrictMock;
23 using ::testing::Values;
24 
25 namespace quic {
26 namespace test {
27 namespace {
28 
29 // Header Acknowledgement decoder stream instruction with stream_id = 1.
30 const char* const kHeaderAcknowledgement = "\x81";
31 
32 const uint64_t kMaximumDynamicTableCapacity = 1024;
33 const uint64_t kMaximumBlockedStreams = 1;
34 
35 class QpackDecoderTest : public QuicTestWithParam<FragmentMode> {
36  protected:
QpackDecoderTest()37   QpackDecoderTest()
38       : qpack_decoder_(kMaximumDynamicTableCapacity, kMaximumBlockedStreams,
39                        &encoder_stream_error_delegate_),
40         fragment_mode_(GetParam()) {
41     qpack_decoder_.set_qpack_stream_sender_delegate(
42         &decoder_stream_sender_delegate_);
43   }
44 
45   ~QpackDecoderTest() override = default;
46 
SetUp()47   void SetUp() override {
48     // Destroy QpackProgressiveDecoder on error to test that it does not crash.
49     // See https://crbug.com/1025209.
50     ON_CALL(handler_, OnDecodingErrorDetected(_, _))
51         .WillByDefault(Invoke([this](QuicErrorCode /* error_code */,
52                                      absl::string_view /* error_message */) {
53           progressive_decoder_.reset();
54         }));
55   }
56 
DecodeEncoderStreamData(absl::string_view data)57   void DecodeEncoderStreamData(absl::string_view data) {
58     qpack_decoder_.encoder_stream_receiver()->Decode(data);
59   }
60 
CreateProgressiveDecoder(QuicStreamId stream_id)61   std::unique_ptr<QpackProgressiveDecoder> CreateProgressiveDecoder(
62       QuicStreamId stream_id) {
63     return qpack_decoder_.CreateProgressiveDecoder(stream_id, &handler_);
64   }
65 
FlushDecoderStream()66   void FlushDecoderStream() { qpack_decoder_.FlushDecoderStream(); }
67 
68   // Set up |progressive_decoder_|.
StartDecoding()69   void StartDecoding() {
70     progressive_decoder_ = CreateProgressiveDecoder(/* stream_id = */ 1);
71   }
72 
73   // Pass header block data to QpackProgressiveDecoder::Decode()
74   // in fragments dictated by |fragment_mode_|.
DecodeData(absl::string_view data)75   void DecodeData(absl::string_view data) {
76     auto fragment_size_generator =
77         FragmentModeToFragmentSizeGenerator(fragment_mode_);
78     while (progressive_decoder_ && !data.empty()) {
79       size_t fragment_size = std::min(fragment_size_generator(), data.size());
80       progressive_decoder_->Decode(data.substr(0, fragment_size));
81       data = data.substr(fragment_size);
82     }
83   }
84 
85   // Signal end of header block to QpackProgressiveDecoder.
EndDecoding()86   void EndDecoding() {
87     if (progressive_decoder_) {
88       progressive_decoder_->EndHeaderBlock();
89     }
90     // If no error was detected, |*progressive_decoder_| is kept alive so that
91     // it can handle callbacks later in case of blocked decoding.
92   }
93 
94   // Decode an entire header block.
DecodeHeaderBlock(absl::string_view data)95   void DecodeHeaderBlock(absl::string_view data) {
96     StartDecoding();
97     DecodeData(data);
98     EndDecoding();
99   }
100 
101   StrictMock<MockEncoderStreamErrorDelegate> encoder_stream_error_delegate_;
102   StrictMock<MockQpackStreamSenderDelegate> decoder_stream_sender_delegate_;
103   StrictMock<MockHeadersHandler> handler_;
104 
105  private:
106   QpackDecoder qpack_decoder_;
107   const FragmentMode fragment_mode_;
108   std::unique_ptr<QpackProgressiveDecoder> progressive_decoder_;
109 };
110 
111 INSTANTIATE_TEST_SUITE_P(All, QpackDecoderTest,
112                          Values(FragmentMode::kSingleChunk,
113                                 FragmentMode::kOctetByOctet));
114 
TEST_P(QpackDecoderTest,NoPrefix)115 TEST_P(QpackDecoderTest, NoPrefix) {
116   EXPECT_CALL(handler_,
117               OnDecodingErrorDetected(QUIC_QPACK_DECOMPRESSION_FAILED,
118                                       Eq("Incomplete header data prefix.")));
119 
120   // Header Data Prefix is at least two bytes long.
121   DecodeHeaderBlock(absl::HexStringToBytes("00"));
122 }
123 
124 // Regression test for https://1025209: QpackProgressiveDecoder must not crash
125 // in Decode() if it is destroyed by handler_.OnDecodingErrorDetected().
TEST_P(QpackDecoderTest,InvalidPrefix)126 TEST_P(QpackDecoderTest, InvalidPrefix) {
127   StartDecoding();
128 
129   EXPECT_CALL(handler_,
130               OnDecodingErrorDetected(QUIC_QPACK_DECOMPRESSION_FAILED,
131                                       Eq("Encoded integer too large.")));
132 
133   // Encoded Required Insert Count in Header Data Prefix is too large.
134   DecodeData(absl::HexStringToBytes("ffffffffffffffffffffffffffff"));
135 }
136 
TEST_P(QpackDecoderTest,EmptyHeaderBlock)137 TEST_P(QpackDecoderTest, EmptyHeaderBlock) {
138   EXPECT_CALL(handler_, OnDecodingCompleted());
139 
140   DecodeHeaderBlock(absl::HexStringToBytes("0000"));
141 }
142 
TEST_P(QpackDecoderTest,LiteralEntryEmptyName)143 TEST_P(QpackDecoderTest, LiteralEntryEmptyName) {
144   EXPECT_CALL(handler_, OnHeaderDecoded(Eq(""), Eq("foo")));
145   EXPECT_CALL(handler_, OnDecodingCompleted());
146 
147   DecodeHeaderBlock(absl::HexStringToBytes("00002003666f6f"));
148 }
149 
TEST_P(QpackDecoderTest,LiteralEntryEmptyValue)150 TEST_P(QpackDecoderTest, LiteralEntryEmptyValue) {
151   EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("")));
152   EXPECT_CALL(handler_, OnDecodingCompleted());
153 
154   DecodeHeaderBlock(absl::HexStringToBytes("000023666f6f00"));
155 }
156 
TEST_P(QpackDecoderTest,LiteralEntryEmptyNameAndValue)157 TEST_P(QpackDecoderTest, LiteralEntryEmptyNameAndValue) {
158   EXPECT_CALL(handler_, OnHeaderDecoded(Eq(""), Eq("")));
159   EXPECT_CALL(handler_, OnDecodingCompleted());
160 
161   DecodeHeaderBlock(absl::HexStringToBytes("00002000"));
162 }
163 
TEST_P(QpackDecoderTest,SimpleLiteralEntry)164 TEST_P(QpackDecoderTest, SimpleLiteralEntry) {
165   EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("bar")));
166   EXPECT_CALL(handler_, OnDecodingCompleted());
167 
168   DecodeHeaderBlock(absl::HexStringToBytes("000023666f6f03626172"));
169 }
170 
TEST_P(QpackDecoderTest,MultipleLiteralEntries)171 TEST_P(QpackDecoderTest, MultipleLiteralEntries) {
172   EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("bar")));
173   std::string str(127, 'a');
174   EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foobaar"), absl::string_view(str)));
175   EXPECT_CALL(handler_, OnDecodingCompleted());
176 
177   DecodeHeaderBlock(absl::HexStringToBytes(
178       "0000"                // prefix
179       "23666f6f03626172"    // foo: bar
180       "2700666f6f62616172"  // 7 octet long header name, the smallest number
181                             // that does not fit on a 3-bit prefix.
182       "7f0061616161616161"  // 127 octet long header value, the smallest number
183       "616161616161616161"  // that does not fit on a 7-bit prefix.
184       "6161616161616161616161616161616161616161616161616161616161616161616161"
185       "6161616161616161616161616161616161616161616161616161616161616161616161"
186       "6161616161616161616161616161616161616161616161616161616161616161616161"
187       "616161616161"));
188 }
189 
190 // Name Length value is too large for varint decoder to decode.
TEST_P(QpackDecoderTest,NameLenTooLargeForVarintDecoder)191 TEST_P(QpackDecoderTest, NameLenTooLargeForVarintDecoder) {
192   EXPECT_CALL(handler_,
193               OnDecodingErrorDetected(QUIC_QPACK_DECOMPRESSION_FAILED,
194                                       Eq("Encoded integer too large.")));
195 
196   DecodeHeaderBlock(absl::HexStringToBytes("000027ffffffffffffffffffff"));
197 }
198 
199 // Name Length value can be decoded by varint decoder but exceeds 1 MB limit.
TEST_P(QpackDecoderTest,NameLenExceedsLimit)200 TEST_P(QpackDecoderTest, NameLenExceedsLimit) {
201   EXPECT_CALL(handler_,
202               OnDecodingErrorDetected(QUIC_QPACK_DECOMPRESSION_FAILED,
203                                       Eq("String literal too long.")));
204 
205   DecodeHeaderBlock(absl::HexStringToBytes("000027ffff7f"));
206 }
207 
208 // Value Length value is too large for varint decoder to decode.
TEST_P(QpackDecoderTest,ValueLenTooLargeForVarintDecoder)209 TEST_P(QpackDecoderTest, ValueLenTooLargeForVarintDecoder) {
210   EXPECT_CALL(handler_,
211               OnDecodingErrorDetected(QUIC_QPACK_DECOMPRESSION_FAILED,
212                                       Eq("Encoded integer too large.")));
213 
214   DecodeHeaderBlock(
215       absl::HexStringToBytes("000023666f6f7fffffffffffffffffffff"));
216 }
217 
218 // Value Length value can be decoded by varint decoder but exceeds 1 MB limit.
TEST_P(QpackDecoderTest,ValueLenExceedsLimit)219 TEST_P(QpackDecoderTest, ValueLenExceedsLimit) {
220   EXPECT_CALL(handler_,
221               OnDecodingErrorDetected(QUIC_QPACK_DECOMPRESSION_FAILED,
222                                       Eq("String literal too long.")));
223 
224   DecodeHeaderBlock(absl::HexStringToBytes("000023666f6f7fffff7f"));
225 }
226 
TEST_P(QpackDecoderTest,LineFeedInValue)227 TEST_P(QpackDecoderTest, LineFeedInValue) {
228   EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("ba\nr")));
229   EXPECT_CALL(handler_, OnDecodingCompleted());
230   DecodeHeaderBlock(absl::HexStringToBytes("000023666f6f0462610a72"));
231 }
232 
TEST_P(QpackDecoderTest,IncompleteHeaderBlock)233 TEST_P(QpackDecoderTest, IncompleteHeaderBlock) {
234   EXPECT_CALL(handler_,
235               OnDecodingErrorDetected(QUIC_QPACK_DECOMPRESSION_FAILED,
236                                       Eq("Incomplete header block.")));
237 
238   DecodeHeaderBlock(absl::HexStringToBytes("00002366"));
239 }
240 
TEST_P(QpackDecoderTest,HuffmanSimple)241 TEST_P(QpackDecoderTest, HuffmanSimple) {
242   EXPECT_CALL(handler_, OnHeaderDecoded(Eq("custom-key"), Eq("custom-value")));
243   EXPECT_CALL(handler_, OnDecodingCompleted());
244 
245   DecodeHeaderBlock(
246       absl::HexStringToBytes("00002f0125a849e95ba97d7f8925a849e95bb8e8b4bf"));
247 }
248 
TEST_P(QpackDecoderTest,AlternatingHuffmanNonHuffman)249 TEST_P(QpackDecoderTest, AlternatingHuffmanNonHuffman) {
250   EXPECT_CALL(handler_, OnHeaderDecoded(Eq("custom-key"), Eq("custom-value")))
251       .Times(4);
252   EXPECT_CALL(handler_, OnDecodingCompleted());
253 
254   DecodeHeaderBlock(absl::HexStringToBytes(
255       "0000"                        // Prefix.
256       "2f0125a849e95ba97d7f"        // Huffman-encoded name.
257       "8925a849e95bb8e8b4bf"        // Huffman-encoded value.
258       "2703637573746f6d2d6b6579"    // Non-Huffman encoded name.
259       "0c637573746f6d2d76616c7565"  // Non-Huffman encoded value.
260       "2f0125a849e95ba97d7f"        // Huffman-encoded name.
261       "0c637573746f6d2d76616c7565"  // Non-Huffman encoded value.
262       "2703637573746f6d2d6b6579"    // Non-Huffman encoded name.
263       "8925a849e95bb8e8b4bf"));     // Huffman-encoded value.
264 }
265 
TEST_P(QpackDecoderTest,HuffmanNameDoesNotHaveEOSPrefix)266 TEST_P(QpackDecoderTest, HuffmanNameDoesNotHaveEOSPrefix) {
267   EXPECT_CALL(handler_,
268               OnDecodingErrorDetected(QUIC_QPACK_DECOMPRESSION_FAILED,
269                                       Eq("Error in Huffman-encoded string.")));
270 
271   // 'y' ends in 0b0 on the most significant bit of the last byte.
272   // The remaining 7 bits must be a prefix of EOS, which is all 1s.
273   DecodeHeaderBlock(
274       absl::HexStringToBytes("00002f0125a849e95ba97d7e8925a849e95bb8e8b4bf"));
275 }
276 
TEST_P(QpackDecoderTest,HuffmanValueDoesNotHaveEOSPrefix)277 TEST_P(QpackDecoderTest, HuffmanValueDoesNotHaveEOSPrefix) {
278   EXPECT_CALL(handler_,
279               OnDecodingErrorDetected(QUIC_QPACK_DECOMPRESSION_FAILED,
280                                       Eq("Error in Huffman-encoded string.")));
281 
282   // 'e' ends in 0b101, taking up the 3 most significant bits of the last byte.
283   // The remaining 5 bits must be a prefix of EOS, which is all 1s.
284   DecodeHeaderBlock(
285       absl::HexStringToBytes("00002f0125a849e95ba97d7f8925a849e95bb8e8b4be"));
286 }
287 
TEST_P(QpackDecoderTest,HuffmanNameEOSPrefixTooLong)288 TEST_P(QpackDecoderTest, HuffmanNameEOSPrefixTooLong) {
289   EXPECT_CALL(handler_,
290               OnDecodingErrorDetected(QUIC_QPACK_DECOMPRESSION_FAILED,
291                                       Eq("Error in Huffman-encoded string.")));
292 
293   // The trailing EOS prefix must be at most 7 bits long.  Appending one octet
294   // with value 0xff is invalid, even though 0b111111111111111 (15 bits) is a
295   // prefix of EOS.
296   DecodeHeaderBlock(
297       absl::HexStringToBytes("00002f0225a849e95ba97d7fff8925a849e95bb8e8b4bf"));
298 }
299 
TEST_P(QpackDecoderTest,HuffmanValueEOSPrefixTooLong)300 TEST_P(QpackDecoderTest, HuffmanValueEOSPrefixTooLong) {
301   EXPECT_CALL(handler_,
302               OnDecodingErrorDetected(QUIC_QPACK_DECOMPRESSION_FAILED,
303                                       Eq("Error in Huffman-encoded string.")));
304 
305   // The trailing EOS prefix must be at most 7 bits long.  Appending one octet
306   // with value 0xff is invalid, even though 0b1111111111111 (13 bits) is a
307   // prefix of EOS.
308   DecodeHeaderBlock(
309       absl::HexStringToBytes("00002f0125a849e95ba97d7f8a25a849e95bb8e8b4bfff"));
310 }
311 
TEST_P(QpackDecoderTest,StaticTable)312 TEST_P(QpackDecoderTest, StaticTable) {
313   // A header name that has multiple entries with different values.
314   EXPECT_CALL(handler_, OnHeaderDecoded(Eq(":method"), Eq("GET")));
315   EXPECT_CALL(handler_, OnHeaderDecoded(Eq(":method"), Eq("POST")));
316   EXPECT_CALL(handler_, OnHeaderDecoded(Eq(":method"), Eq("TRACE")));
317 
318   // A header name that has a single entry with non-empty value.
319   EXPECT_CALL(handler_,
320               OnHeaderDecoded(Eq("accept-encoding"), Eq("gzip, deflate, br")));
321   EXPECT_CALL(handler_, OnHeaderDecoded(Eq("accept-encoding"), Eq("compress")));
322   EXPECT_CALL(handler_, OnHeaderDecoded(Eq("accept-encoding"), Eq("")));
323 
324   // A header name that has a single entry with empty value.
325   EXPECT_CALL(handler_, OnHeaderDecoded(Eq("location"), Eq("")));
326   EXPECT_CALL(handler_, OnHeaderDecoded(Eq("location"), Eq("foo")));
327 
328   EXPECT_CALL(handler_, OnDecodingCompleted());
329 
330   DecodeHeaderBlock(absl::HexStringToBytes(
331       "0000d1dfccd45f108621e9aec2a11f5c8294e75f000554524143455f1000"));
332 }
333 
TEST_P(QpackDecoderTest,TooHighStaticTableIndex)334 TEST_P(QpackDecoderTest, TooHighStaticTableIndex) {
335   // This is the last entry in the static table with index 98.
336   EXPECT_CALL(handler_,
337               OnHeaderDecoded(Eq("x-frame-options"), Eq("sameorigin")));
338 
339   // Addressing entry 99 should trigger an error.
340   EXPECT_CALL(handler_,
341               OnDecodingErrorDetected(QUIC_QPACK_DECOMPRESSION_FAILED,
342                                       Eq("Static table entry not found.")));
343 
344   DecodeHeaderBlock(absl::HexStringToBytes("0000ff23ff24"));
345 }
346 
TEST_P(QpackDecoderTest,DynamicTable)347 TEST_P(QpackDecoderTest, DynamicTable) {
348   DecodeEncoderStreamData(absl::HexStringToBytes(
349       "3fe107"          // Set dynamic table capacity to 1024.
350       "6294e703626172"  // Add literal entry with name "foo" and value "bar".
351       "80035a5a5a"      // Add entry with name of dynamic table entry index 0
352                         // (relative index) and value "ZZZ".
353       "cf8294e7"        // Add entry with name of static table entry index 15
354                         // and value "foo".
355       "01"));           // Duplicate entry with relative index 1.
356 
357   // Now there are four entries in the dynamic table.
358   // Entry 0: "foo", "bar"
359   // Entry 1: "foo", "ZZZ"
360   // Entry 2: ":method", "foo"
361   // Entry 3: "foo", "ZZZ"
362 
363   // Use a Sequence to test that mock methods are called in order.
364   Sequence s;
365 
366   EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("bar"))).InSequence(s);
367   EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("ZZZ"))).InSequence(s);
368   EXPECT_CALL(handler_, OnHeaderDecoded(Eq(":method"), Eq("foo")))
369       .InSequence(s);
370   EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("ZZZ"))).InSequence(s);
371   EXPECT_CALL(handler_, OnHeaderDecoded(Eq(":method"), Eq("ZZ"))).InSequence(s);
372   if (!GetQuicRestartFlag(quic_opport_bundle_qpack_decoder_data2)) {
373     EXPECT_CALL(decoder_stream_sender_delegate_,
374                 WriteStreamData(Eq(kHeaderAcknowledgement)))
375         .InSequence(s);
376   }
377   EXPECT_CALL(handler_, OnDecodingCompleted()).InSequence(s);
378   if (GetQuicRestartFlag(quic_opport_bundle_qpack_decoder_data2)) {
379     EXPECT_CALL(decoder_stream_sender_delegate_,
380                 WriteStreamData(Eq(kHeaderAcknowledgement)))
381         .InSequence(s);
382   }
383 
384   DecodeHeaderBlock(absl::HexStringToBytes(
385       "0500"  // Required Insert Count 4 and Delta Base 0.
386               // Base is 4 + 0 = 4.
387       "83"    // Dynamic table entry with relative index 3, absolute index 0.
388       "82"    // Dynamic table entry with relative index 2, absolute index 1.
389       "81"    // Dynamic table entry with relative index 1, absolute index 2.
390       "80"    // Dynamic table entry with relative index 0, absolute index 3.
391       "41025a5a"));  // Name of entry 1 (relative index) from dynamic table,
392                      // with value "ZZ".
393   if (GetQuicRestartFlag(quic_opport_bundle_qpack_decoder_data2)) {
394     FlushDecoderStream();
395   }
396 
397   EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("bar"))).InSequence(s);
398   EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("ZZZ"))).InSequence(s);
399   EXPECT_CALL(handler_, OnHeaderDecoded(Eq(":method"), Eq("foo")))
400       .InSequence(s);
401   EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("ZZZ"))).InSequence(s);
402   EXPECT_CALL(handler_, OnHeaderDecoded(Eq(":method"), Eq("ZZ"))).InSequence(s);
403   if (!GetQuicRestartFlag(quic_opport_bundle_qpack_decoder_data2)) {
404     EXPECT_CALL(decoder_stream_sender_delegate_,
405                 WriteStreamData(Eq(kHeaderAcknowledgement)))
406         .InSequence(s);
407   }
408   EXPECT_CALL(handler_, OnDecodingCompleted()).InSequence(s);
409   if (GetQuicRestartFlag(quic_opport_bundle_qpack_decoder_data2)) {
410     EXPECT_CALL(decoder_stream_sender_delegate_,
411                 WriteStreamData(Eq(kHeaderAcknowledgement)))
412         .InSequence(s);
413   }
414 
415   DecodeHeaderBlock(absl::HexStringToBytes(
416       "0502"  // Required Insert Count 4 and Delta Base 2.
417               // Base is 4 + 2 = 6.
418       "85"    // Dynamic table entry with relative index 5, absolute index 0.
419       "84"    // Dynamic table entry with relative index 4, absolute index 1.
420       "83"    // Dynamic table entry with relative index 3, absolute index 2.
421       "82"    // Dynamic table entry with relative index 2, absolute index 3.
422       "43025a5a"));  // Name of entry 3 (relative index) from dynamic table,
423                      // with value "ZZ".
424   if (GetQuicRestartFlag(quic_opport_bundle_qpack_decoder_data2)) {
425     FlushDecoderStream();
426   }
427 
428   EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("bar"))).InSequence(s);
429   EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("ZZZ"))).InSequence(s);
430   EXPECT_CALL(handler_, OnHeaderDecoded(Eq(":method"), Eq("foo")))
431       .InSequence(s);
432   EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("ZZZ"))).InSequence(s);
433   EXPECT_CALL(handler_, OnHeaderDecoded(Eq(":method"), Eq("ZZ"))).InSequence(s);
434   if (!GetQuicRestartFlag(quic_opport_bundle_qpack_decoder_data2)) {
435     EXPECT_CALL(decoder_stream_sender_delegate_,
436                 WriteStreamData(Eq(kHeaderAcknowledgement)))
437         .InSequence(s);
438   }
439   EXPECT_CALL(handler_, OnDecodingCompleted()).InSequence(s);
440   if (GetQuicRestartFlag(quic_opport_bundle_qpack_decoder_data2)) {
441     EXPECT_CALL(decoder_stream_sender_delegate_,
442                 WriteStreamData(Eq(kHeaderAcknowledgement)))
443         .InSequence(s);
444   }
445 
446   DecodeHeaderBlock(absl::HexStringToBytes(
447       "0582"  // Required Insert Count 4 and Delta Base 2 with sign bit set.
448               // Base is 4 - 2 - 1 = 1.
449       "80"    // Dynamic table entry with relative index 0, absolute index 0.
450       "10"    // Dynamic table entry with post-base index 0, absolute index 1.
451       "11"    // Dynamic table entry with post-base index 1, absolute index 2.
452       "12"    // Dynamic table entry with post-base index 2, absolute index 3.
453       "01025a5a"));  // Name of entry 1 (post-base index) from dynamic table,
454                      // with value "ZZ".
455   if (GetQuicRestartFlag(quic_opport_bundle_qpack_decoder_data2)) {
456     FlushDecoderStream();
457   }
458 }
459 
TEST_P(QpackDecoderTest,DecreasingDynamicTableCapacityEvictsEntries)460 TEST_P(QpackDecoderTest, DecreasingDynamicTableCapacityEvictsEntries) {
461   // Set dynamic table capacity to 1024.
462   DecodeEncoderStreamData(absl::HexStringToBytes("3fe107"));
463   // Add literal entry with name "foo" and value "bar".
464   DecodeEncoderStreamData(absl::HexStringToBytes("6294e703626172"));
465 
466   EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("bar")));
467   EXPECT_CALL(handler_, OnDecodingCompleted());
468   EXPECT_CALL(decoder_stream_sender_delegate_,
469               WriteStreamData(Eq(kHeaderAcknowledgement)));
470 
471   DecodeHeaderBlock(absl::HexStringToBytes(
472       "0200"   // Required Insert Count 1 and Delta Base 0.
473                // Base is 1 + 0 = 1.
474       "80"));  // Dynamic table entry with relative index 0, absolute index 0.
475 
476   // Change dynamic table capacity to 32 bytes, smaller than the entry.
477   // This must cause the entry to be evicted.
478   DecodeEncoderStreamData(absl::HexStringToBytes("3f01"));
479 
480   EXPECT_CALL(handler_, OnDecodingErrorDetected(
481                             QUIC_QPACK_DECOMPRESSION_FAILED,
482                             Eq("Dynamic table entry already evicted.")));
483 
484   DecodeHeaderBlock(absl::HexStringToBytes(
485       "0200"   // Required Insert Count 1 and Delta Base 0.
486                // Base is 1 + 0 = 1.
487       "80"));  // Dynamic table entry with relative index 0, absolute index 0.
488   if (GetQuicRestartFlag(quic_opport_bundle_qpack_decoder_data2)) {
489     FlushDecoderStream();
490   }
491 }
492 
TEST_P(QpackDecoderTest,EncoderStreamErrorEntryTooLarge)493 TEST_P(QpackDecoderTest, EncoderStreamErrorEntryTooLarge) {
494   EXPECT_CALL(
495       encoder_stream_error_delegate_,
496       OnEncoderStreamError(QUIC_QPACK_ENCODER_STREAM_ERROR_INSERTING_LITERAL,
497                            Eq("Error inserting literal entry.")));
498 
499   // Set dynamic table capacity to 34.
500   DecodeEncoderStreamData(absl::HexStringToBytes("3f03"));
501   // Add literal entry with name "foo" and value "bar", size is 32 + 3 + 3 = 38.
502   DecodeEncoderStreamData(absl::HexStringToBytes("6294e703626172"));
503 }
504 
TEST_P(QpackDecoderTest,EncoderStreamErrorInvalidStaticTableEntry)505 TEST_P(QpackDecoderTest, EncoderStreamErrorInvalidStaticTableEntry) {
506   EXPECT_CALL(
507       encoder_stream_error_delegate_,
508       OnEncoderStreamError(QUIC_QPACK_ENCODER_STREAM_INVALID_STATIC_ENTRY,
509                            Eq("Invalid static table entry.")));
510 
511   // Address invalid static table entry index 99.
512   DecodeEncoderStreamData(absl::HexStringToBytes("ff2400"));
513 }
514 
TEST_P(QpackDecoderTest,EncoderStreamErrorInvalidDynamicTableEntry)515 TEST_P(QpackDecoderTest, EncoderStreamErrorInvalidDynamicTableEntry) {
516   EXPECT_CALL(encoder_stream_error_delegate_,
517               OnEncoderStreamError(
518                   QUIC_QPACK_ENCODER_STREAM_INSERTION_INVALID_RELATIVE_INDEX,
519                   Eq("Invalid relative index.")));
520 
521   DecodeEncoderStreamData(absl::HexStringToBytes(
522       "3fe107"          // Set dynamic table capacity to 1024.
523       "6294e703626172"  // Add literal entry with name "foo" and value "bar".
524       "8100"));  // Address dynamic table entry with relative index 1.  Such
525                  // entry does not exist.  The most recently added and only
526                  // dynamic table entry has relative index 0.
527 }
528 
TEST_P(QpackDecoderTest,EncoderStreamErrorDuplicateInvalidEntry)529 TEST_P(QpackDecoderTest, EncoderStreamErrorDuplicateInvalidEntry) {
530   EXPECT_CALL(encoder_stream_error_delegate_,
531               OnEncoderStreamError(
532                   QUIC_QPACK_ENCODER_STREAM_DUPLICATE_INVALID_RELATIVE_INDEX,
533                   Eq("Invalid relative index.")));
534 
535   DecodeEncoderStreamData(absl::HexStringToBytes(
536       "3fe107"          // Set dynamic table capacity to 1024.
537       "6294e703626172"  // Add literal entry with name "foo" and value "bar".
538       "01"));  // Duplicate dynamic table entry with relative index 1.  Such
539                // entry does not exist.  The most recently added and only
540                // dynamic table entry has relative index 0.
541 }
542 
TEST_P(QpackDecoderTest,EncoderStreamErrorTooLargeInteger)543 TEST_P(QpackDecoderTest, EncoderStreamErrorTooLargeInteger) {
544   EXPECT_CALL(encoder_stream_error_delegate_,
545               OnEncoderStreamError(QUIC_QPACK_ENCODER_STREAM_INTEGER_TOO_LARGE,
546                                    Eq("Encoded integer too large.")));
547 
548   DecodeEncoderStreamData(absl::HexStringToBytes("3fffffffffffffffffffff"));
549 }
550 
TEST_P(QpackDecoderTest,InvalidDynamicEntryWhenBaseIsZero)551 TEST_P(QpackDecoderTest, InvalidDynamicEntryWhenBaseIsZero) {
552   EXPECT_CALL(handler_, OnDecodingErrorDetected(QUIC_QPACK_DECOMPRESSION_FAILED,
553                                                 Eq("Invalid relative index.")));
554 
555   // Set dynamic table capacity to 1024.
556   DecodeEncoderStreamData(absl::HexStringToBytes("3fe107"));
557   // Add literal entry with name "foo" and value "bar".
558   DecodeEncoderStreamData(absl::HexStringToBytes("6294e703626172"));
559 
560   DecodeHeaderBlock(absl::HexStringToBytes(
561       "0280"   // Required Insert Count is 1.  Base 1 - 1 - 0 = 0 is explicitly
562                // permitted by the spec.
563       "80"));  // However, addressing entry with relative index 0 would point to
564                // absolute index -1, which is invalid.
565 }
566 
TEST_P(QpackDecoderTest,InvalidNegativeBase)567 TEST_P(QpackDecoderTest, InvalidNegativeBase) {
568   EXPECT_CALL(handler_, OnDecodingErrorDetected(QUIC_QPACK_DECOMPRESSION_FAILED,
569                                                 Eq("Error calculating Base.")));
570 
571   // Required Insert Count 1, Delta Base 1 with sign bit set, Base would
572   // be 1 - 1 - 1 = -1, but it is not allowed to be negative.
573   DecodeHeaderBlock(absl::HexStringToBytes("0281"));
574 }
575 
TEST_P(QpackDecoderTest,InvalidDynamicEntryByRelativeIndex)576 TEST_P(QpackDecoderTest, InvalidDynamicEntryByRelativeIndex) {
577   // Set dynamic table capacity to 1024.
578   DecodeEncoderStreamData(absl::HexStringToBytes("3fe107"));
579   // Add literal entry with name "foo" and value "bar".
580   DecodeEncoderStreamData(absl::HexStringToBytes("6294e703626172"));
581 
582   EXPECT_CALL(handler_, OnDecodingErrorDetected(QUIC_QPACK_DECOMPRESSION_FAILED,
583                                                 Eq("Invalid relative index.")));
584 
585   DecodeHeaderBlock(absl::HexStringToBytes(
586       "0200"   // Required Insert Count 1 and Delta Base 0.
587                // Base is 1 + 0 = 1.
588       "81"));  // Indexed Header Field instruction addressing relative index 1.
589                // This is absolute index -1, which is invalid.
590 
591   EXPECT_CALL(handler_, OnDecodingErrorDetected(QUIC_QPACK_DECOMPRESSION_FAILED,
592                                                 Eq("Invalid relative index.")));
593 
594   DecodeHeaderBlock(absl::HexStringToBytes(
595       "0200"     // Required Insert Count 1 and Delta Base 0.
596                  // Base is 1 + 0 = 1.
597       "4100"));  // Literal Header Field with Name Reference instruction
598                  // addressing relative index 1.  This is absolute index -1,
599                  // which is invalid.
600 }
601 
TEST_P(QpackDecoderTest,EvictedDynamicTableEntry)602 TEST_P(QpackDecoderTest, EvictedDynamicTableEntry) {
603   // Update dynamic table capacity to 128.
604   DecodeEncoderStreamData(absl::HexStringToBytes("3f61"));
605 
606   // Add literal entry with name "foo" and value "bar", size 32 + 3 + 3 = 38.
607   // This fits in the table three times.
608   DecodeEncoderStreamData(absl::HexStringToBytes("6294e703626172"));
609   // Duplicate entry four times.  This evicts the first two instances.
610   DecodeEncoderStreamData(absl::HexStringToBytes("00000000"));
611 
612   EXPECT_CALL(handler_, OnDecodingErrorDetected(
613                             QUIC_QPACK_DECOMPRESSION_FAILED,
614                             Eq("Dynamic table entry already evicted.")));
615 
616   DecodeHeaderBlock(absl::HexStringToBytes(
617       "0500"   // Required Insert Count 4 and Delta Base 0.
618                // Base is 4 + 0 = 4.
619       "82"));  // Indexed Header Field instruction addressing relative index 2.
620                // This is absolute index 1. Such entry does not exist.
621 
622   EXPECT_CALL(handler_, OnDecodingErrorDetected(
623                             QUIC_QPACK_DECOMPRESSION_FAILED,
624                             Eq("Dynamic table entry already evicted.")));
625 
626   DecodeHeaderBlock(absl::HexStringToBytes(
627       "0500"     // Required Insert Count 4 and Delta Base 0.
628                  // Base is 4 + 0 = 4.
629       "4200"));  // Literal Header Field with Name Reference instruction
630                  // addressing relative index 2.  This is absolute index 1. Such
631                  // entry does not exist.
632 
633   EXPECT_CALL(handler_, OnDecodingErrorDetected(
634                             QUIC_QPACK_DECOMPRESSION_FAILED,
635                             Eq("Dynamic table entry already evicted.")));
636 
637   DecodeHeaderBlock(absl::HexStringToBytes(
638       "0380"   // Required Insert Count 2 and Delta Base 0 with sign bit set.
639                // Base is 2 - 0 - 1 = 1
640       "10"));  // Indexed Header Field instruction addressing dynamic table
641                // entry with post-base index 0, absolute index 1.  Such entry
642                // does not exist.
643 
644   EXPECT_CALL(handler_, OnDecodingErrorDetected(
645                             QUIC_QPACK_DECOMPRESSION_FAILED,
646                             Eq("Dynamic table entry already evicted.")));
647 
648   DecodeHeaderBlock(absl::HexStringToBytes(
649       "0380"     // Required Insert Count 2 and Delta Base 0 with sign bit set.
650                  // Base is 2 - 0 - 1 = 1
651       "0000"));  // Literal Header Field With Name Reference instruction
652                  // addressing dynamic table entry with post-base index 0,
653                  // absolute index 1.  Such entry does not exist.
654 }
655 
TEST_P(QpackDecoderTest,TableCapacityMustNotExceedMaximum)656 TEST_P(QpackDecoderTest, TableCapacityMustNotExceedMaximum) {
657   EXPECT_CALL(
658       encoder_stream_error_delegate_,
659       OnEncoderStreamError(QUIC_QPACK_ENCODER_STREAM_SET_DYNAMIC_TABLE_CAPACITY,
660                            Eq("Error updating dynamic table capacity.")));
661 
662   // Try to update dynamic table capacity to 2048, which exceeds the maximum.
663   DecodeEncoderStreamData(absl::HexStringToBytes("3fe10f"));
664 }
665 
TEST_P(QpackDecoderTest,SetDynamicTableCapacity)666 TEST_P(QpackDecoderTest, SetDynamicTableCapacity) {
667   // Update dynamic table capacity to 128, which does not exceed the maximum.
668   DecodeEncoderStreamData(absl::HexStringToBytes("3f61"));
669 }
670 
TEST_P(QpackDecoderTest,InvalidEncodedRequiredInsertCount)671 TEST_P(QpackDecoderTest, InvalidEncodedRequiredInsertCount) {
672   // Maximum dynamic table capacity is 1024.
673   // MaxEntries is 1024 / 32 = 32.
674   // Required Insert Count is decoded modulo 2 * MaxEntries, that is, modulo 64.
675   // A value of 1 cannot be encoded as 65 even though it has the same remainder.
676   EXPECT_CALL(handler_, OnDecodingErrorDetected(
677                             QUIC_QPACK_DECOMPRESSION_FAILED,
678                             Eq("Error decoding Required Insert Count.")));
679   DecodeHeaderBlock(absl::HexStringToBytes("4100"));
680 }
681 
682 // Regression test for https://crbug.com/970218:  Decoder must stop processing
683 // after a Header Block Prefix with an invalid Encoded Required Insert Count.
TEST_P(QpackDecoderTest,DataAfterInvalidEncodedRequiredInsertCount)684 TEST_P(QpackDecoderTest, DataAfterInvalidEncodedRequiredInsertCount) {
685   EXPECT_CALL(handler_, OnDecodingErrorDetected(
686                             QUIC_QPACK_DECOMPRESSION_FAILED,
687                             Eq("Error decoding Required Insert Count.")));
688   // Header Block Prefix followed by some extra data.
689   DecodeHeaderBlock(absl::HexStringToBytes("410000"));
690 }
691 
TEST_P(QpackDecoderTest,WrappedRequiredInsertCount)692 TEST_P(QpackDecoderTest, WrappedRequiredInsertCount) {
693   // Maximum dynamic table capacity is 1024.
694   // MaxEntries is 1024 / 32 = 32.
695 
696   // Set dynamic table capacity to 1024.
697   DecodeEncoderStreamData(absl::HexStringToBytes("3fe107"));
698   // Add literal entry with name "foo" and a 600 byte long value.  This will fit
699   // in the dynamic table once but not twice.
700   DecodeEncoderStreamData(
701       absl::HexStringToBytes("6294e7"     // Name "foo".
702                              "7fd903"));  // Value length 600.
703   std::string header_value(600, 'Z');
704   DecodeEncoderStreamData(header_value);
705 
706   // Duplicate most recent entry 200 times.
707   DecodeEncoderStreamData(std::string(200, '\x00'));
708 
709   // Now there is only one entry in the dynamic table, with absolute index 200.
710 
711   EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq(header_value)));
712   EXPECT_CALL(handler_, OnDecodingCompleted());
713   EXPECT_CALL(decoder_stream_sender_delegate_,
714               WriteStreamData(Eq(kHeaderAcknowledgement)));
715 
716   // Send header block with Required Insert Count = 201.
717   DecodeHeaderBlock(absl::HexStringToBytes(
718       "0a00"   // Encoded Required Insert Count 10, Required Insert Count 201,
719                // Delta Base 0, Base 201.
720       "80"));  // Emit dynamic table entry with relative index 0.
721   if (GetQuicRestartFlag(quic_opport_bundle_qpack_decoder_data2)) {
722     FlushDecoderStream();
723   }
724 }
725 
TEST_P(QpackDecoderTest,NonZeroRequiredInsertCountButNoDynamicEntries)726 TEST_P(QpackDecoderTest, NonZeroRequiredInsertCountButNoDynamicEntries) {
727   // Set dynamic table capacity to 1024.
728   DecodeEncoderStreamData(absl::HexStringToBytes("3fe107"));
729   // Add literal entry with name "foo" and value "bar".
730   DecodeEncoderStreamData(absl::HexStringToBytes("6294e703626172"));
731 
732   EXPECT_CALL(handler_, OnHeaderDecoded(Eq(":method"), Eq("GET")));
733   EXPECT_CALL(handler_,
734               OnDecodingErrorDetected(QUIC_QPACK_DECOMPRESSION_FAILED,
735                                       Eq("Required Insert Count too large.")));
736 
737   DecodeHeaderBlock(absl::HexStringToBytes(
738       "0200"   // Required Insert Count is 1.
739       "d1"));  // But the only instruction references the static table.
740 }
741 
TEST_P(QpackDecoderTest,AddressEntryNotAllowedByRequiredInsertCount)742 TEST_P(QpackDecoderTest, AddressEntryNotAllowedByRequiredInsertCount) {
743   // Set dynamic table capacity to 1024.
744   DecodeEncoderStreamData(absl::HexStringToBytes("3fe107"));
745   // Add literal entry with name "foo" and value "bar".
746   DecodeEncoderStreamData(absl::HexStringToBytes("6294e703626172"));
747 
748   EXPECT_CALL(
749       handler_,
750       OnDecodingErrorDetected(
751           QUIC_QPACK_DECOMPRESSION_FAILED,
752           Eq("Absolute Index must be smaller than Required Insert Count.")));
753 
754   DecodeHeaderBlock(absl::HexStringToBytes(
755       "0201"   // Required Insert Count 1 and Delta Base 1.
756                // Base is 1 + 1 = 2.
757       "80"));  // Indexed Header Field instruction addressing dynamic table
758                // entry with relative index 0, absolute index 1.  This is not
759                // allowed by Required Insert Count.
760 
761   EXPECT_CALL(
762       handler_,
763       OnDecodingErrorDetected(
764           QUIC_QPACK_DECOMPRESSION_FAILED,
765           Eq("Absolute Index must be smaller than Required Insert Count.")));
766 
767   DecodeHeaderBlock(absl::HexStringToBytes(
768       "0201"     // Required Insert Count 1 and Delta Base 1.
769                  // Base is 1 + 1 = 2.
770       "4000"));  // Literal Header Field with Name Reference instruction
771                  // addressing dynamic table entry with relative index 0,
772                  // absolute index 1.  This is not allowed by Required Index
773                  // Count.
774 
775   EXPECT_CALL(
776       handler_,
777       OnDecodingErrorDetected(
778           QUIC_QPACK_DECOMPRESSION_FAILED,
779           Eq("Absolute Index must be smaller than Required Insert Count.")));
780 
781   DecodeHeaderBlock(absl::HexStringToBytes(
782       "0200"   // Required Insert Count 1 and Delta Base 0.
783                // Base is 1 + 0 = 1.
784       "10"));  // Indexed Header Field with Post-Base Index instruction
785                // addressing dynamic table entry with post-base index 0,
786                // absolute index 1.  This is not allowed by Required Insert
787                // Count.
788 
789   EXPECT_CALL(
790       handler_,
791       OnDecodingErrorDetected(
792           QUIC_QPACK_DECOMPRESSION_FAILED,
793           Eq("Absolute Index must be smaller than Required Insert Count.")));
794 
795   DecodeHeaderBlock(absl::HexStringToBytes(
796       "0200"     // Required Insert Count 1 and Delta Base 0.
797                  // Base is 1 + 0 = 1.
798       "0000"));  // Literal Header Field with Post-Base Name Reference
799                  // instruction addressing dynamic table entry with post-base
800                  // index 0, absolute index 1.  This is not allowed by Required
801                  // Index Count.
802 }
803 
TEST_P(QpackDecoderTest,PromisedRequiredInsertCountLargerThanActual)804 TEST_P(QpackDecoderTest, PromisedRequiredInsertCountLargerThanActual) {
805   // Set dynamic table capacity to 1024.
806   DecodeEncoderStreamData(absl::HexStringToBytes("3fe107"));
807   // Add literal entry with name "foo" and value "bar".
808   DecodeEncoderStreamData(absl::HexStringToBytes("6294e703626172"));
809   // Duplicate entry twice so that decoding of header blocks with Required
810   // Insert Count not exceeding 3 is not blocked.
811   DecodeEncoderStreamData(absl::HexStringToBytes("00"));
812   DecodeEncoderStreamData(absl::HexStringToBytes("00"));
813 
814   EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("bar")));
815   EXPECT_CALL(handler_,
816               OnDecodingErrorDetected(QUIC_QPACK_DECOMPRESSION_FAILED,
817                                       Eq("Required Insert Count too large.")));
818 
819   DecodeHeaderBlock(absl::HexStringToBytes(
820       "0300"   // Required Insert Count 2 and Delta Base 0.
821                // Base is 2 + 0 = 2.
822       "81"));  // Indexed Header Field instruction addressing dynamic table
823                // entry with relative index 1, absolute index 0.  Header block
824                // requires insert count of 1, even though Required Insert Count
825                // is 2.
826 
827   EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("")));
828   EXPECT_CALL(handler_,
829               OnDecodingErrorDetected(QUIC_QPACK_DECOMPRESSION_FAILED,
830                                       Eq("Required Insert Count too large.")));
831 
832   DecodeHeaderBlock(absl::HexStringToBytes(
833       "0300"     // Required Insert Count 2 and Delta Base 0.
834                  // Base is 2 + 0 = 2.
835       "4100"));  // Literal Header Field with Name Reference instruction
836                  // addressing dynamic table entry with relative index 1,
837                  // absolute index 0.  Header block requires insert count of 1,
838                  // even though Required Insert Count is 2.
839 
840   EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("bar")));
841   EXPECT_CALL(handler_,
842               OnDecodingErrorDetected(QUIC_QPACK_DECOMPRESSION_FAILED,
843                                       Eq("Required Insert Count too large.")));
844 
845   DecodeHeaderBlock(absl::HexStringToBytes(
846       "0481"   // Required Insert Count 3 and Delta Base 1 with sign bit set.
847                // Base is 3 - 1 - 1 = 1.
848       "10"));  // Indexed Header Field with Post-Base Index instruction
849                // addressing dynamic table entry with post-base index 0,
850                // absolute index 1.  Header block requires insert count of 2,
851                // even though Required Insert Count is 3.
852 
853   EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("")));
854   EXPECT_CALL(handler_,
855               OnDecodingErrorDetected(QUIC_QPACK_DECOMPRESSION_FAILED,
856                                       Eq("Required Insert Count too large.")));
857 
858   DecodeHeaderBlock(absl::HexStringToBytes(
859       "0481"     // Required Insert Count 3 and Delta Base 1 with sign bit set.
860                  // Base is 3 - 1 - 1 = 1.
861       "0000"));  // Literal Header Field with Post-Base Name Reference
862                  // instruction addressing dynamic table entry with post-base
863                  // index 0, absolute index 1.  Header block requires insert
864                  // count of 2, even though Required Insert Count is 3.
865 }
866 
TEST_P(QpackDecoderTest,BlockedDecoding)867 TEST_P(QpackDecoderTest, BlockedDecoding) {
868   DecodeHeaderBlock(absl::HexStringToBytes(
869       "0200"   // Required Insert Count 1 and Delta Base 0.
870                // Base is 1 + 0 = 1.
871       "80"));  // Indexed Header Field instruction addressing dynamic table
872                // entry with relative index 0, absolute index 0.
873 
874   EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("bar")));
875   EXPECT_CALL(handler_, OnDecodingCompleted());
876   EXPECT_CALL(decoder_stream_sender_delegate_,
877               WriteStreamData(Eq(kHeaderAcknowledgement)));
878 
879   // Set dynamic table capacity to 1024.
880   DecodeEncoderStreamData(absl::HexStringToBytes("3fe107"));
881   // Add literal entry with name "foo" and value "bar".
882   DecodeEncoderStreamData(absl::HexStringToBytes("6294e703626172"));
883   if (GetQuicRestartFlag(quic_opport_bundle_qpack_decoder_data2)) {
884     FlushDecoderStream();
885   }
886 }
887 
TEST_P(QpackDecoderTest,BlockedDecodingUnblockedBeforeEndOfHeaderBlock)888 TEST_P(QpackDecoderTest, BlockedDecodingUnblockedBeforeEndOfHeaderBlock) {
889   StartDecoding();
890   DecodeData(absl::HexStringToBytes(
891       "0200"   // Required Insert Count 1 and Delta Base 0.
892                // Base is 1 + 0 = 1.
893       "80"     // Indexed Header Field instruction addressing dynamic table
894                // entry with relative index 0, absolute index 0.
895       "d1"));  // Static table entry with index 17.
896 
897   // Set dynamic table capacity to 1024.
898   DecodeEncoderStreamData(absl::HexStringToBytes("3fe107"));
899 
900   // Add literal entry with name "foo" and value "bar".  Decoding is now
901   // unblocked because dynamic table Insert Count reached the Required Insert
902   // Count of the header block.  |handler_| methods are called immediately for
903   // the already consumed part of the header block.
904   EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("bar")));
905   EXPECT_CALL(handler_, OnHeaderDecoded(Eq(":method"), Eq("GET")));
906   DecodeEncoderStreamData(absl::HexStringToBytes("6294e703626172"));
907   Mock::VerifyAndClearExpectations(&handler_);
908 
909   // Rest of header block is processed by QpackProgressiveDecoder
910   // in the unblocked state.
911   EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("bar")));
912   EXPECT_CALL(handler_, OnHeaderDecoded(Eq(":scheme"), Eq("https")));
913   DecodeData(absl::HexStringToBytes(
914       "80"     // Indexed Header Field instruction addressing dynamic table
915                // entry with relative index 0, absolute index 0.
916       "d7"));  // Static table entry with index 23.
917   Mock::VerifyAndClearExpectations(&handler_);
918 
919   EXPECT_CALL(handler_, OnDecodingCompleted());
920   EXPECT_CALL(decoder_stream_sender_delegate_,
921               WriteStreamData(Eq(kHeaderAcknowledgement)));
922   EndDecoding();
923   if (GetQuicRestartFlag(quic_opport_bundle_qpack_decoder_data2)) {
924     FlushDecoderStream();
925   }
926 }
927 
928 // Regression test for https://crbug.com/1024263.
TEST_P(QpackDecoderTest,BlockedDecodingUnblockedAndErrorBeforeEndOfHeaderBlock)929 TEST_P(QpackDecoderTest,
930        BlockedDecodingUnblockedAndErrorBeforeEndOfHeaderBlock) {
931   StartDecoding();
932   DecodeData(absl::HexStringToBytes(
933       "0200"   // Required Insert Count 1 and Delta Base 0.
934                // Base is 1 + 0 = 1.
935       "80"     // Indexed Header Field instruction addressing dynamic table
936                // entry with relative index 0, absolute index 0.
937       "81"));  // Relative index 1 is equal to Base, therefore invalid.
938 
939   // Set dynamic table capacity to 1024.
940   DecodeEncoderStreamData(absl::HexStringToBytes("3fe107"));
941 
942   // Add literal entry with name "foo" and value "bar".  Decoding is now
943   // unblocked because dynamic table Insert Count reached the Required Insert
944   // Count of the header block.  |handler_| methods are called immediately for
945   // the already consumed part of the header block.
946   EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("bar")));
947   EXPECT_CALL(handler_, OnDecodingErrorDetected(QUIC_QPACK_DECOMPRESSION_FAILED,
948                                                 Eq("Invalid relative index.")));
949   DecodeEncoderStreamData(absl::HexStringToBytes("6294e703626172"));
950 }
951 
952 // Make sure that Required Insert Count is compared to Insert Count,
953 // not size of dynamic table.
TEST_P(QpackDecoderTest,BlockedDecodingAndEvictedEntries)954 TEST_P(QpackDecoderTest, BlockedDecodingAndEvictedEntries) {
955   // Update dynamic table capacity to 128.
956   // At most three non-empty entries fit in the dynamic table.
957   DecodeEncoderStreamData(absl::HexStringToBytes("3f61"));
958 
959   DecodeHeaderBlock(absl::HexStringToBytes(
960       "0700"   // Required Insert Count 6 and Delta Base 0.
961                // Base is 6 + 0 = 6.
962       "80"));  // Indexed Header Field instruction addressing dynamic table
963                // entry with relative index 0, absolute index 5.
964 
965   // Add literal entry with name "foo" and value "bar".
966   DecodeEncoderStreamData(absl::HexStringToBytes("6294e703626172"));
967 
968   // Duplicate entry four times.  This evicts the first two instances.
969   DecodeEncoderStreamData(absl::HexStringToBytes("00000000"));
970 
971   EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("baz")));
972   EXPECT_CALL(handler_, OnDecodingCompleted());
973   EXPECT_CALL(decoder_stream_sender_delegate_,
974               WriteStreamData(Eq(kHeaderAcknowledgement)));
975 
976   // Add literal entry with name "foo" and value "bar".
977   // Insert Count is now 6, reaching Required Insert Count of the header block.
978   DecodeEncoderStreamData(absl::HexStringToBytes("6294e70362617a"));
979   if (GetQuicRestartFlag(quic_opport_bundle_qpack_decoder_data2)) {
980     FlushDecoderStream();
981   }
982 }
983 
TEST_P(QpackDecoderTest,TooManyBlockedStreams)984 TEST_P(QpackDecoderTest, TooManyBlockedStreams) {
985   // Required Insert Count 1 and Delta Base 0.
986   // Without any dynamic table entries received, decoding is blocked.
987   std::string data = absl::HexStringToBytes("0200");
988 
989   auto progressive_decoder1 = CreateProgressiveDecoder(/* stream_id = */ 1);
990   progressive_decoder1->Decode(data);
991 
992   EXPECT_CALL(handler_,
993               OnDecodingErrorDetected(
994                   QUIC_QPACK_DECOMPRESSION_FAILED,
995                   Eq("Limit on number of blocked streams exceeded.")));
996 
997   auto progressive_decoder2 = CreateProgressiveDecoder(/* stream_id = */ 2);
998   progressive_decoder2->Decode(data);
999 }
1000 
TEST_P(QpackDecoderTest,InsertCountIncrement)1001 TEST_P(QpackDecoderTest, InsertCountIncrement) {
1002   DecodeEncoderStreamData(absl::HexStringToBytes(
1003       "3fe107"          // Set dynamic table capacity to 1024.
1004       "6294e703626172"  // Add literal entry with name "foo" and value "bar".
1005       "00"));           // Duplicate entry.
1006 
1007   EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("bar")));
1008   EXPECT_CALL(handler_, OnDecodingCompleted());
1009 
1010   // Decoder received two insertions, but Header Acknowledgement only increases
1011   // Known Insert Count to one.  Decoder should send an Insert Count Increment
1012   // instruction with increment of one to update Known Insert Count to two.
1013   EXPECT_CALL(decoder_stream_sender_delegate_,
1014               WriteStreamData(Eq(absl::HexStringToBytes(
1015                   "81"       // Header Acknowledgement on stream 1
1016                   "01"))));  // Insert Count Increment with increment of one
1017 
1018   DecodeHeaderBlock(absl::HexStringToBytes(
1019       "0200"   // Required Insert Count 1 and Delta Base 0.
1020                // Base is 1 + 0 = 1.
1021       "80"));  // Dynamic table entry with relative index 0, absolute index 0.
1022   if (GetQuicRestartFlag(quic_opport_bundle_qpack_decoder_data2)) {
1023     FlushDecoderStream();
1024   }
1025 }
1026 
1027 }  // namespace
1028 }  // namespace test
1029 }  // namespace quic
1030