Handle null session in MoqtLivePublisher::OnNewObjectAvailable. When a MoQT session is closing, visitor()->session() returns nullptr. Add a check to return early when the session is null to prevent null pointer dereferences. PiperOrigin-RevId: 986962626
diff --git a/quiche/quic/moqt/moqt_live_publisher.cc b/quiche/quic/moqt/moqt_live_publisher.cc index 0bdfb64..a67ddad 100644 --- a/quiche/quic/moqt/moqt_live_publisher.cc +++ b/quiche/quic/moqt/moqt_live_publisher.cc
@@ -184,7 +184,7 @@ // TODO(vasilvv): This currently sends UINT64_MAX for datagram subgroups. // Maybe do something more satisfactory? SessionToPublisherInterface* session_info = visitor(); - if (session_info == nullptr) { + if (session_info == nullptr || session_info->session() == nullptr) { return; // Session is gone. } session_info->trace_recorder().RecordNewObjectAvaliable(
diff --git a/quiche/quic/moqt/moqt_live_publisher_test.cc b/quiche/quic/moqt/moqt_live_publisher_test.cc index d70fd0d..ed67d2a 100644 --- a/quiche/quic/moqt/moqt_live_publisher_test.cc +++ b/quiche/quic/moqt/moqt_live_publisher_test.cc
@@ -732,6 +732,20 @@ publisher_->OnSubgroupAbandoned(1, 0, 1234); } +// Repro for b/565145319. A new object arrives while the session is closing. +TEST_F(LivePublisherTest, OnNewObjectAvailableSessionClosing) { + CreateStream(Location(1, 0), 0, 128); + // When MoqtSession::is_closing_ is true, session() returns nullptr. + EXPECT_CALL(visitor_, session).WillRepeatedly(Return(nullptr)); + EXPECT_CALL(*track_publisher_, + GetCachedObject(1, std::make_optional<uint64_t>(0), 1, 0)) + .Times(testing::AtMost(1)) + .WillOnce(Return(DefaultPublishedObject(Location(1, 1), 0, 128))); + EXPECT_CALL(monitoring_interface_, OnNewObjectEnqueued(Location(1, 1))) + .Times(testing::AtMost(1)); + publisher_->OnNewObjectAvailable(Location(1, 1), 0, 128); +} + } // namespace } // namespace moqt::test