Avoid performing pending stream actions after the connection is closed.

gfe-relnote: v99 only, not in prod.
PiperOrigin-RevId: 254805203
Change-Id: I6b7dbc36097d5e8c95a03c3f58a1ef0e32452316
diff --git a/quic/core/http/quic_spdy_session.cc b/quic/core/http/quic_spdy_session.cc
index 55ceb2a..3ef610e 100644
--- a/quic/core/http/quic_spdy_session.cc
+++ b/quic/core/http/quic_spdy_session.cc
@@ -748,6 +748,7 @@
 
 bool QuicSpdySession::ProcessPendingStream(PendingStream* pending) {
   DCHECK(VersionHasStreamType(connection()->transport_version()));
+  DCHECK(connection()->connected());
   struct iovec iov;
   if (!pending->sequencer()->GetReadableRegion(&iov)) {
     // The first byte hasn't been received yet.
diff --git a/quic/core/http/quic_spdy_session_test.cc b/quic/core/http/quic_spdy_session_test.cc
index 919a4fe..1819f40 100644
--- a/quic/core/http/quic_spdy_session_test.cc
+++ b/quic/core/http/quic_spdy_session_test.cc
@@ -1654,6 +1654,24 @@
   EXPECT_TRUE(session_.UsesPendingStreams());
 }
 
+// Regression test for crbug.com/977581.
+TEST_P(QuicSpdySessionTestClient, BadStreamFramePendingStream) {
+  if (!VersionHasStreamType(transport_version())) {
+    return;
+  }
+
+  EXPECT_EQ(0u, session_.GetNumOpenIncomingStreams());
+  QuicStreamId stream_id1 =
+      GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 0);
+  // A bad stream frame with no data and no fin.
+  QuicStreamFrame data1(stream_id1, false, 0, 0);
+  EXPECT_CALL(*connection_, CloseConnection(_, _, _))
+      .WillOnce(
+          Invoke(connection_, &MockQuicConnection::ReallyCloseConnection));
+  EXPECT_CALL(*connection_, SendConnectionClosePacket(_, _));
+  session_.OnStreamFrame(data1);
+}
+
 TEST_P(QuicSpdySessionTestClient, AvailableStreamsClient) {
   ASSERT_TRUE(session_.GetOrCreateDynamicStream(
                   GetNthServerInitiatedBidirectionalId(2)) != nullptr);
diff --git a/quic/core/quic_session.cc b/quic/core/quic_session.cc
index 0671b8e..5c5d9a6 100644
--- a/quic/core/quic_session.cc
+++ b/quic/core/quic_session.cc
@@ -174,6 +174,9 @@
   }
 
   pending->OnStreamFrame(frame);
+  if (!connection()->connected()) {
+    return;
+  }
   if (ProcessPendingStream(pending)) {
     // The pending stream should now be in the scope of normal streams.
     DCHECK(IsClosedStream(stream_id) || IsOpenStream(stream_id))