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))