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