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