Simplify QpackDecodedHeadersAccumulator API.

Fix handling of blocked headers that contain an error in the part that is
buffered and then processed when unblocked before reading the entire header
block is over, see https://crbug.com/1024263.

Simplify QpackDecodedHeadersAccumulator and Visitor API such that Visitor
methods are always called instead of Decode() and EndHeaderBlock() signalling
error in return value in the synchronous case.

This allows for a simpler QpackDecodedHeadersAccumulator, QuicSpdyStream, and
QpackRoundTripFuzzer implementation.  Also it makes it easier to improve the
handling of headers exceeding the limit in a future CL.

gfe-relnote: n/a, change to QUIC v99-only code.  Protected by existing disabled gfe2_reloadable_flag_quic_enable_version_99.
PiperOrigin-RevId: 280327626
Change-Id: Ifc60f6f530340ddb3f40e2861cc353e7abd89422
diff --git a/quic/core/qpack/qpack_decoder_test.cc b/quic/core/qpack/qpack_decoder_test.cc
index 5d05904..323a893 100644
--- a/quic/core/qpack/qpack_decoder_test.cc
+++ b/quic/core/qpack/qpack_decoder_test.cc
@@ -780,16 +780,15 @@
                // entry with relative index 0, absolute index 0.
       "d1"));  // Static table entry with index 17.
 
+  // Set dynamic table capacity to 1024.
+  DecodeEncoderStreamData(QuicTextUtils::HexDecode("3fe107"));
+
   // Add literal entry with name "foo" and value "bar".  Decoding is now
   // unblocked because dynamic table Insert Count reached the Required Insert
   // Count of the header block.  |handler_| methods are called immediately for
   // the already consumed part of the header block.
   EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("bar")));
   EXPECT_CALL(handler_, OnHeaderDecoded(Eq(":method"), Eq("GET")));
-
-  // Set dynamic table capacity to 1024.
-  DecodeEncoderStreamData(QuicTextUtils::HexDecode("3fe107"));
-  // Add literal entry with name "foo" and value "bar".
   DecodeEncoderStreamData(QuicTextUtils::HexDecode("6294e703626172"));
   Mock::VerifyAndClearExpectations(&handler_);
 
@@ -809,6 +808,29 @@
   EndDecoding();
 }
 
+// Regression test for https://crbug.com/1024263.
+TEST_P(QpackDecoderTest,
+       BlockedDecodingUnblockedAndErrorBeforeEndOfHeaderBlock) {
+  StartDecoding();
+  DecodeData(QuicTextUtils::HexDecode(
+      "0200"   // Required Insert Count 1 and Delta Base 0.
+               // Base is 1 + 0 = 1.
+      "80"     // Indexed Header Field instruction addressing dynamic table
+               // entry with relative index 0, absolute index 0.
+      "81"));  // Relative index 1 is equal to Base, therefore invalid.
+
+  // Set dynamic table capacity to 1024.
+  DecodeEncoderStreamData(QuicTextUtils::HexDecode("3fe107"));
+
+  // Add literal entry with name "foo" and value "bar".  Decoding is now
+  // unblocked because dynamic table Insert Count reached the Required Insert
+  // Count of the header block.  |handler_| methods are called immediately for
+  // the already consumed part of the header block.
+  EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("bar")));
+  EXPECT_CALL(handler_, OnDecodingErrorDetected(Eq("Invalid relative index.")));
+  DecodeEncoderStreamData(QuicTextUtils::HexDecode("6294e703626172"));
+}
+
 // Make sure that Required Insert Count is compared to Insert Count,
 // not size of dynamic table.
 TEST_P(QpackDecoderTest, BlockedDecodingAndEvictedEntries) {