Add a getstringifcomplete function to hpackdecoderstringbuffer to return string only when state is complete. used in error details, not protected.

PiperOrigin-RevId: 323777904
Change-Id: I9beb5ace10f4ceb0aeed76bb8c37015ce808a8f6
diff --git a/http2/hpack/decoder/hpack_decoder_string_buffer.cc b/http2/hpack/decoder/hpack_decoder_string_buffer.cc
index d38ea9f..f461c1e 100644
--- a/http2/hpack/decoder/hpack_decoder_string_buffer.cc
+++ b/http2/hpack/decoder/hpack_decoder_string_buffer.cc
@@ -194,6 +194,14 @@
   return value_;
 }
 
+quiche::QuicheStringPiece HpackDecoderStringBuffer::GetStringIfComplete()
+    const {
+  if (state_ != State::COMPLETE) {
+    return {};
+  }
+  return str();
+}
+
 std::string HpackDecoderStringBuffer::ReleaseString() {
   HTTP2_DVLOG(3) << "HpackDecoderStringBuffer::ReleaseString";
   DCHECK_EQ(state_, State::COMPLETE);
diff --git a/http2/hpack/decoder/hpack_decoder_string_buffer.h b/http2/hpack/decoder/hpack_decoder_string_buffer.h
index 1ae8e6b..1341e79 100644
--- a/http2/hpack/decoder/hpack_decoder_string_buffer.h
+++ b/http2/hpack/decoder/hpack_decoder_string_buffer.h
@@ -53,6 +53,9 @@
   // transport buffers).
   quiche::QuicheStringPiece str() const;
 
+  // Same as str() if state_ is COMPLETE. Otherwise, returns empty string piece.
+  quiche::QuicheStringPiece GetStringIfComplete() const;
+
   // Returns the completely collected string by value, using std::move in an
   // effort to avoid unnecessary copies. ReleaseString() must not be called
   // unless the string has been buffered (to avoid forcing a potentially
diff --git a/http2/hpack/decoder/hpack_whole_entry_buffer.cc b/http2/hpack/decoder/hpack_whole_entry_buffer.cc
index dc93d1e..f8d5e9d 100644
--- a/http2/hpack/decoder/hpack_whole_entry_buffer.cc
+++ b/http2/hpack/decoder/hpack_whole_entry_buffer.cc
@@ -93,7 +93,7 @@
   if (!error_detected_) {
     if (len > max_string_size_bytes_) {
       std::string detailed_error = quiche::QuicheStrCat(
-          "Value length (", len, ") of [", name_.str(),
+          "Value length (", len, ") of [", name_.GetStringIfComplete(),
           "] is longer than permitted (", max_string_size_bytes_, ")");
       HTTP2_DVLOG(1) << detailed_error;
       ReportError(HpackDecodingError::kValueTooLong, detailed_error);
diff --git a/http2/hpack/decoder/hpack_whole_entry_buffer_test.cc b/http2/hpack/decoder/hpack_whole_entry_buffer_test.cc
index 2396bd6..70e1350 100644
--- a/http2/hpack/decoder/hpack_whole_entry_buffer_test.cc
+++ b/http2/hpack/decoder/hpack_whole_entry_buffer_test.cc
@@ -180,6 +180,16 @@
   entry_buffer_.OnValueStart(false, kMaxStringSize + 1);
 }
 
+// Regression test for b/162141899.
+TEST_F(HpackWholeEntryBufferTest, ValueTooLongWithoutName) {
+  entry_buffer_.OnStartLiteralHeader(HpackEntryType::kIndexedLiteralHeader, 1);
+  EXPECT_CALL(listener_,
+              OnHpackDecodeError(
+                  HpackDecodingError::kValueTooLong,
+                  "Value length (21) of [] is longer than permitted (20)"));
+  entry_buffer_.OnValueStart(false, kMaxStringSize + 1);
+}
+
 // Verify that a Huffman encoded name with an explicit EOS generates an error
 // for an explicit EOS.
 TEST_F(HpackWholeEntryBufferTest, NameHuffmanError) {