Uses the new `HpackEncoder` dynamic table upper bound added in a previous commit.

This will only affect behavior for users who set `OgHttp2Session::Options::max_hpack_encoding_table_capacity`.

This should fix https://github.com/envoyproxy/envoy/issues/38689.

Protected by does not affect the GFE2 binary; not protected.

PiperOrigin-RevId: 757879310
diff --git a/quiche/http2/adapter/oghttp2_session.cc b/quiche/http2/adapter/oghttp2_session.cc
index 2a5ec62..c25b291 100644
--- a/quiche/http2/adapter/oghttp2_session.cc
+++ b/quiche/http2/adapter/oghttp2_session.cc
@@ -187,13 +187,6 @@
   return status.size() == 3 && status[0] == '1';
 }
 
-// Returns the upper bound on HPACK encoder table capacity. If not specified in
-// the Options, a reasonable default upper bound is used.
-uint32_t HpackCapacityBound(const OgHttp2Session::Options& o) {
-  return o.max_hpack_encoding_table_capacity.value_or(
-      kMaximumHpackTableCapacity);
-}
-
 bool IsNonAckSettings(const spdy::SpdyFrameIR& frame) {
   return frame.frame_type() == spdy::SpdyFrameType::SETTINGS &&
          !reinterpret_cast<const SpdySettingsIR&>(frame).is_ack();
@@ -381,7 +374,7 @@
       max_outbound_concurrent_streams_(
           options.remote_max_concurrent_streams.value_or(100u)) {
   decoder_.set_visitor(&receive_logger_);
-  if (options_.max_header_list_bytes) {
+  if (options_.max_header_list_bytes.has_value()) {
     // Limit buffering of encoded HPACK data to 2x the decoded limit.
     decoder_.GetHpackDecoder().set_max_decode_buffer_size_bytes(
         2 * *options_.max_header_list_bytes);
@@ -389,9 +382,9 @@
     decoder_.GetHpackDecoder().set_max_header_block_bytes(
         4 * *options_.max_header_list_bytes);
   }
-  if (IsServerSession()) {
-    remaining_preface_ = {spdy::kHttp2ConnectionHeaderPrefix,
-                          spdy::kHttp2ConnectionHeaderPrefixSize};
+  if (options_.max_hpack_encoding_table_capacity.has_value()) {
+    framer_.GetHpackEncoder()->SetHeaderTableSizeBound(
+        *options_.max_hpack_encoding_table_capacity);
   }
   if (options_.max_header_field_size.has_value()) {
     headers_handler_.SetMaxFieldSize(*options_.max_header_field_size);
@@ -402,6 +395,10 @@
     // endpoints don't properly handle multiple `Cookie` header fields.
     framer_.GetHpackEncoder()->DisableCookieCrumbling();
   }
+  if (IsServerSession()) {
+    remaining_preface_ = {spdy::kHttp2ConnectionHeaderPrefix,
+                          spdy::kHttp2ConnectionHeaderPrefixSize};
+  }
 }
 
 OgHttp2Session::~OgHttp2Session() {}
@@ -1309,7 +1306,7 @@
 void OgHttp2Session::OnSetting(spdy::SpdySettingsId id, uint32_t value) {
   switch (id) {
     case HEADER_TABLE_SIZE:
-      value = std::min(value, HpackCapacityBound(options_));
+      value = std::min(value, kMaximumHpackTableCapacity);
       if (value < framer_.GetHpackEncoder()->CurrentHeaderTableSizeSetting()) {
         // Safe to apply a smaller table capacity immediately.
         QUICHE_VLOG(3) << TracePerspectiveAsString(options_.perspective)
diff --git a/quiche/http2/adapter/oghttp2_session_test.cc b/quiche/http2/adapter/oghttp2_session_test.cc
index 58da30e..34a387b 100644
--- a/quiche/http2/adapter/oghttp2_session_test.cc
+++ b/quiche/http2/adapter/oghttp2_session_test.cc
@@ -395,8 +395,8 @@
                         true, nullptr);
   int result = session.Send();
   ASSERT_EQ(result, 0);
-  // BUG: the encoder table size should not have grown beyond zero.
-  EXPECT_LT(0, session.GetHpackEncoderDynamicTableSize());
+  // The encoder table size should not have grown beyond zero.
+  EXPECT_EQ(session.GetHpackEncoderDynamicTableSize(), 0);
 }
 
 TEST(OgHttp2SessionTest, ClientSubmitRequestWithLargePayload) {
@@ -801,6 +801,32 @@
   EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS}));
 }
 
+// Demonstrates that the dynamic table size setting interpreted from the peer
+// won't exceed the hardcoded 64kB upper bound.
+TEST(OgHttp2SessionTest, ServerDynamicTableSizeAboveUpperBound) {
+  TestVisitor visitor;
+  OgHttp2Session::Options options;
+  options.perspective = Perspective::kServer;
+  OgHttp2Session session(visitor, options);
+
+  const std::string frames =
+      TestFrameSequence()
+          .ClientPreface({{HEADER_TABLE_SIZE, 100u * 1024u}})
+          .Serialize();
+  testing::InSequence s;
+
+  // Client preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 6, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  // Although the peer adverised 100kB, the server interprets the setting value
+  // with a 64kB upper bound.
+  EXPECT_CALL(visitor, OnSetting(Http2Setting{HEADER_TABLE_SIZE, 64u * 1024u}));
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  const int64_t result = session.ProcessBytes(frames);
+  EXPECT_EQ(frames.size(), static_cast<size_t>(result));
+}
+
 TEST(OgHttp2SessionTest, ServerSubmitResponse) {
   TestVisitor visitor;
   OgHttp2Session::Options options;