Removes the QUICHE_BUG that limits HTTP/2 DATA frame payload sizes to 16kB.

This should fix the fuzz test failure found in b/266766513.

PiperOrigin-RevId: 505787095
diff --git a/quiche/http2/adapter/oghttp2_session_test.cc b/quiche/http2/adapter/oghttp2_session_test.cc
index f536cd7..2953f1e 100644
--- a/quiche/http2/adapter/oghttp2_session_test.cc
+++ b/quiche/http2/adapter/oghttp2_session_test.cc
@@ -324,6 +324,82 @@
             kInitialFlowControlWindowSize);
 }
 
+TEST(OgHttp2SessionTest, ClientSubmitRequestWithLargePayload) {
+  DataSavingVisitor visitor;
+  OgHttp2Session::Options options;
+  options.perspective = Perspective::kClient;
+  OgHttp2Session session(visitor, options);
+
+  EXPECT_FALSE(session.want_write());
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
+
+  // Even though the user has not queued any frames for the session, it should
+  // still send the connection preface.
+  int result = session.Send();
+  EXPECT_EQ(0, result);
+  absl::string_view serialized = visitor.data();
+  EXPECT_THAT(serialized,
+              testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
+  serialized.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
+  // Initial SETTINGS.
+  EXPECT_THAT(serialized, EqualsFrames({SpdyFrameType::SETTINGS}));
+  visitor.Clear();
+
+  const std::string initial_frames =
+      TestFrameSequence()
+          .ServerPreface(
+              {Http2Setting{Http2KnownSettingsId::MAX_FRAME_SIZE, 32768u}})
+          .Serialize();
+  testing::InSequence s;
+
+  // Server preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 6, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSetting(Http2Setting{
+                           Http2KnownSettingsId::MAX_FRAME_SIZE, 32768u}));
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  const int64_t initial_result = session.ProcessBytes(initial_frames);
+  EXPECT_EQ(initial_frames.size(), static_cast<size_t>(initial_result));
+
+  // Session will want to write a SETTINGS ack.
+  EXPECT_TRUE(session.want_write());
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
+
+  result = session.Send();
+  EXPECT_EQ(0, result);
+  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS}));
+  visitor.Clear();
+
+  auto body1 = std::make_unique<TestDataFrameSource>(visitor, true);
+  body1->AppendPayload(std::string(20000, 'a'));
+  body1->EndData();
+  int stream_id =
+      session.SubmitRequest(ToHeaders({{":method", "POST"},
+                                       {":scheme", "http"},
+                                       {":authority", "example.com"},
+                                       {":path", "/this/is/request/one"}}),
+                            std::move(body1), nullptr);
+  EXPECT_GT(stream_id, 0);
+  EXPECT_TRUE(session.want_write());
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id, _, 0x4));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id, _, 0x4, 0));
+  // Single DATA frame with fin, indicating all 20k bytes fit in one frame.
+  EXPECT_CALL(visitor, OnFrameSent(DATA, stream_id, _, 0x1, 0));
+
+  result = session.Send();
+  EXPECT_EQ(0, result);
+  EXPECT_THAT(visitor.data(), EqualsFrames({spdy::SpdyFrameType::HEADERS,
+                                            spdy::SpdyFrameType::DATA}));
+  visitor.Clear();
+  EXPECT_FALSE(session.want_write());
+}
+
 // This test exercises the case where the client request body source is read
 // blocked.
 TEST(OgHttp2SessionTest, ClientSubmitRequestWithReadBlock) {
diff --git a/quiche/spdy/core/spdy_frame_builder.cc b/quiche/spdy/core/spdy_frame_builder.cc
index c0558ac..be6885e 100644
--- a/quiche/spdy/core/spdy_frame_builder.cc
+++ b/quiche/spdy/core/spdy_frame_builder.cc
@@ -88,8 +88,10 @@
   uint8_t raw_frame_type = SerializeFrameType(type);
   QUICHE_DCHECK(IsDefinedFrameType(raw_frame_type));
   QUICHE_DCHECK_EQ(0u, stream_id & ~kStreamIdMask);
-  QUICHE_BUG_IF(spdy_bug_73_2, length > kHttp2DefaultFramePayloadLimit)
-      << "Frame length  " << length_ << " is longer than frame size limit.";
+  // From https://www.rfc-editor.org/rfc/rfc9113#name-frame-size
+  const size_t kProtocolFrameSizeLimit = (1 << 24) - 1;
+  QUICHE_BUG_IF(spdy_bug_73_2, length > kProtocolFrameSizeLimit)
+      << "Frame length  " << length << " is longer than frame size limit.";
   return BeginNewFrameInternal(raw_frame_type, flags, stream_id, length);
 }