Prevent RTCStatsCollector crash for stopped transceivers Prevent a crash in RTCStatsCollector that occurs when attempting to process transceivers with a stopped direction. When gathering statistics, the collector iterates through all available transceivers. If a transceiver's current direction is set to kStopped, the internal mapping for media information is not created during the preparation phase and there was a missing check for that. Bug: b/494115682 Change-Id: I0748c9d627d886aaa12118411fa94e2ab8575269 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/458680 Reviewed-by: Evan Shrubsole <eshr@webrtc.org> Commit-Queue: Tomas Gunnarsson <tommi@webrtc.org> Cr-Commit-Position: refs/heads/main@{#47221}
diff --git a/pc/rtc_stats_collector.cc b/pc/rtc_stats_collector.cc index 6a2325b..8030dd4 100644 --- a/pc/rtc_stats_collector.cc +++ b/pc/rtc_stats_collector.cc
@@ -1862,6 +1862,10 @@ continue; } + if (stats.current_direction == RtpTransceiverDirection::kStopped) { + continue; + } + if (stats.media_type == MediaType::AUDIO) { ProduceAudioRTPStreamStats_s(timestamp, stats, call_stats, audio_device_stats, report);
diff --git a/pc/rtc_stats_collector_unittest.cc b/pc/rtc_stats_collector_unittest.cc index c044f87..2b5e4b0 100644 --- a/pc/rtc_stats_collector_unittest.cc +++ b/pc/rtc_stats_collector_unittest.cc
@@ -68,6 +68,7 @@ #include "pc/media_stream.h" #include "pc/peer_connection_internal.h" #include "pc/rtp_sender.h" +#include "pc/rtp_transceiver.h" #include "pc/sctp_data_channel.h" #include "pc/stream_collection.h" #include "pc/test/fake_audio_track.h" @@ -102,6 +103,9 @@ #include "test/time_controller/simulated_time_controller.h" using ::testing::_; +using ::testing::IsEmpty; +using ::testing::Not; +using ::testing::NotNull; using ::testing::Return; namespace webrtc { @@ -900,6 +904,34 @@ EXPECT_EQ(report->size(), json_value.size()); } +TEST_P(RTCStatsCollectorTest, ProduceRTPStreamStatsWithStoppedTransceiver) { + const char kTransportName[] = "transport"; + const char kMid[] = "VideoMid"; + + VideoMediaInfo video_media_info; + video_media_info.senders.emplace_back(); + video_media_info.senders[0].add_ssrc(1); + + RTC_ALLOW_PLAN_B_DEPRECATION_BEGIN(); + pc_->AddVideoChannel(kMid, kTransportName, video_media_info); + RTC_ALLOW_PLAN_B_DEPRECATION_END(); + + // Get the transceiver and set it to stopped. + std::vector<scoped_refptr<RtpTransceiverProxyWithInternal<RtpTransceiver>>> + transceivers = pc_->GetTransceiversInternal(); + ASSERT_THAT(transceivers, Not(IsEmpty())); + scoped_refptr<RtpTransceiverProxyWithInternal<RtpTransceiver>> transceiver = + transceivers[0]; + ASSERT_TRUE(transceiver); + transceiver->internal()->set_current_direction( + RtpTransceiverDirection::kStopped); + + // This should not crash. + scoped_refptr<const RTCStatsReport> report = + stats_->GetStatsReport(main_thread_); + EXPECT_THAT(report, NotNull()); +} + TEST_P(RTCStatsCollectorTest, CollectRTCCertificateStatsSingle) { const char kTransportName[] = "transport";