[ObjC] Validate and store strong ref to peer_connection before use.

Some methods used a weak peer_connection reference directly,
supposedly causing crashes.
Now, both peer_connection and delegate are captured as
strong references and validated before use for consistency.

Bug: webrtc:393263500
Change-Id: I0ab39acf7097d4c8082d05749b37b6d4998f9aa7
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/375880
Reviewed-by: Kári Helgason <kthelgason@webrtc.org>
Commit-Queue: Yury Yarashevich <yura.yaroshevich@gmail.com>
Cr-Commit-Position: refs/heads/main@{#43839}
This commit is contained in:
Yury Yarashevich 2025-01-30 13:18:48 +01:00 committed by WebRTC LUCI CQ
parent b60a5ab91c
commit f80562d22a

View File

@ -138,107 +138,192 @@ void PeerConnectionDelegateAdapter::OnSignalingChange(
RTCSignalingState state = [[RTC_OBJC_TYPE(RTCPeerConnection) class] RTCSignalingState state = [[RTC_OBJC_TYPE(RTCPeerConnection) class]
signalingStateForNativeState:new_state]; signalingStateForNativeState:new_state];
RTC_OBJC_TYPE(RTCPeerConnection) *peer_connection = peer_connection_; RTC_OBJC_TYPE(RTCPeerConnection) *peer_connection = peer_connection_;
[peer_connection.delegate peerConnection:peer_connection if (peer_connection == nil) {
didChangeSignalingState:state]; return;
}
id<RTC_OBJC_TYPE(RTCPeerConnectionDelegate)> delegate =
peer_connection.delegate;
if (delegate == nil) {
return;
}
[delegate peerConnection:peer_connection didChangeSignalingState:state];
} }
void PeerConnectionDelegateAdapter::OnAddStream( void PeerConnectionDelegateAdapter::OnAddStream(
rtc::scoped_refptr<MediaStreamInterface> stream) { rtc::scoped_refptr<MediaStreamInterface> stream) {
RTC_OBJC_TYPE(RTCPeerConnection) *peer_connection = peer_connection_; RTC_OBJC_TYPE(RTCPeerConnection) *peer_connection = peer_connection_;
RTC_OBJC_TYPE(RTCMediaStream) *mediaStream = [[RTC_OBJC_TYPE(RTCMediaStream) if (peer_connection == nil) {
return;
}
id<RTC_OBJC_TYPE(RTCPeerConnectionDelegate)> delegate =
peer_connection.delegate;
if (delegate == nil) {
return;
}
RTC_OBJC_TYPE(RTCMediaStream) *media_stream = [[RTC_OBJC_TYPE(RTCMediaStream)
alloc] initWithFactory:peer_connection.factory nativeMediaStream:stream]; alloc] initWithFactory:peer_connection.factory nativeMediaStream:stream];
[peer_connection.delegate peerConnection:peer_connection
didAddStream:mediaStream]; [delegate peerConnection:peer_connection didAddStream:media_stream];
} }
void PeerConnectionDelegateAdapter::OnRemoveStream( void PeerConnectionDelegateAdapter::OnRemoveStream(
rtc::scoped_refptr<MediaStreamInterface> stream) { rtc::scoped_refptr<MediaStreamInterface> stream) {
RTC_OBJC_TYPE(RTCPeerConnection) *peer_connection = peer_connection_; RTC_OBJC_TYPE(RTCPeerConnection) *peer_connection = peer_connection_;
if (peer_connection == nil) {
return;
}
id<RTC_OBJC_TYPE(RTCPeerConnectionDelegate)> delegate =
peer_connection.delegate;
if (delegate == nil) {
return;
}
RTC_OBJC_TYPE(RTCMediaStream) *mediaStream = [[RTC_OBJC_TYPE(RTCMediaStream) RTC_OBJC_TYPE(RTCMediaStream) *mediaStream = [[RTC_OBJC_TYPE(RTCMediaStream)
alloc] initWithFactory:peer_connection.factory nativeMediaStream:stream]; alloc] initWithFactory:peer_connection.factory nativeMediaStream:stream];
[peer_connection.delegate peerConnection:peer_connection [delegate peerConnection:peer_connection didRemoveStream:mediaStream];
didRemoveStream:mediaStream];
} }
void PeerConnectionDelegateAdapter::OnTrack( void PeerConnectionDelegateAdapter::OnTrack(
rtc::scoped_refptr<RtpTransceiverInterface> nativeTransceiver) { rtc::scoped_refptr<RtpTransceiverInterface> nativeTransceiver) {
RTC_OBJC_TYPE(RTCPeerConnection) *peer_connection = peer_connection_; RTC_OBJC_TYPE(RTCPeerConnection) *peer_connection = peer_connection_;
if (peer_connection == nil) {
return;
}
id<RTC_OBJC_TYPE(RTCPeerConnectionDelegate)> delegate =
peer_connection.delegate;
if (delegate == nil) {
return;
}
RTC_OBJC_TYPE(RTCRtpTransceiver) *transceiver = RTC_OBJC_TYPE(RTCRtpTransceiver) *transceiver =
[[RTC_OBJC_TYPE(RTCRtpTransceiver) alloc] [[RTC_OBJC_TYPE(RTCRtpTransceiver) alloc]
initWithFactory:peer_connection.factory initWithFactory:peer_connection.factory
nativeRtpTransceiver:nativeTransceiver]; nativeRtpTransceiver:nativeTransceiver];
if ([peer_connection.delegate if ([delegate respondsToSelector:@selector(peerConnection:
respondsToSelector:@selector(peerConnection: didStartReceivingOnTransceiver:)]) {
didStartReceivingOnTransceiver:)]) { [delegate peerConnection:peer_connection
[peer_connection.delegate peerConnection:peer_connection didStartReceivingOnTransceiver:transceiver];
didStartReceivingOnTransceiver:transceiver];
} }
} }
void PeerConnectionDelegateAdapter::OnDataChannel( void PeerConnectionDelegateAdapter::OnDataChannel(
rtc::scoped_refptr<DataChannelInterface> data_channel) { rtc::scoped_refptr<DataChannelInterface> data_channel) {
RTC_OBJC_TYPE(RTCPeerConnection) *peer_connection = peer_connection_; RTC_OBJC_TYPE(RTCPeerConnection) *peer_connection = peer_connection_;
if (peer_connection == nil) {
return;
}
id<RTC_OBJC_TYPE(RTCPeerConnectionDelegate)> delegate =
peer_connection.delegate;
if (delegate == nil) {
return;
}
RTC_OBJC_TYPE(RTCDataChannel) *dataChannel = [[RTC_OBJC_TYPE(RTCDataChannel) RTC_OBJC_TYPE(RTCDataChannel) *dataChannel = [[RTC_OBJC_TYPE(RTCDataChannel)
alloc] initWithFactory:peer_connection.factory alloc] initWithFactory:peer_connection.factory
nativeDataChannel:data_channel]; nativeDataChannel:data_channel];
[peer_connection.delegate peerConnection:peer_connection [delegate peerConnection:peer_connection didOpenDataChannel:dataChannel];
didOpenDataChannel:dataChannel];
} }
void PeerConnectionDelegateAdapter::OnRenegotiationNeeded() { void PeerConnectionDelegateAdapter::OnRenegotiationNeeded() {
RTC_OBJC_TYPE(RTCPeerConnection) *peer_connection = peer_connection_; RTC_OBJC_TYPE(RTCPeerConnection) *peer_connection = peer_connection_;
[peer_connection.delegate peerConnectionShouldNegotiate:peer_connection]; if (peer_connection == nil) {
return;
}
id<RTC_OBJC_TYPE(RTCPeerConnectionDelegate)> delegate =
peer_connection.delegate;
if (delegate == nil) {
return;
}
[delegate peerConnectionShouldNegotiate:peer_connection];
} }
void PeerConnectionDelegateAdapter::OnIceConnectionChange( void PeerConnectionDelegateAdapter::OnIceConnectionChange(
PeerConnectionInterface::IceConnectionState new_state) { PeerConnectionInterface::IceConnectionState new_state) {
RTC_OBJC_TYPE(RTCPeerConnection) *peer_connection = peer_connection_;
if (peer_connection == nil) {
return;
}
id<RTC_OBJC_TYPE(RTCPeerConnectionDelegate)> delegate =
peer_connection.delegate;
if (delegate == nil) {
return;
}
RTCIceConnectionState state = [RTC_OBJC_TYPE(RTCPeerConnection) RTCIceConnectionState state = [RTC_OBJC_TYPE(RTCPeerConnection)
iceConnectionStateForNativeState:new_state]; iceConnectionStateForNativeState:new_state];
[peer_connection_.delegate peerConnection:peer_connection_ [delegate peerConnection:peer_connection didChangeIceConnectionState:state];
didChangeIceConnectionState:state];
} }
void PeerConnectionDelegateAdapter::OnStandardizedIceConnectionChange( void PeerConnectionDelegateAdapter::OnStandardizedIceConnectionChange(
PeerConnectionInterface::IceConnectionState new_state) { PeerConnectionInterface::IceConnectionState new_state) {
if ([peer_connection_.delegate RTC_OBJC_TYPE(RTCPeerConnection) *peer_connection = peer_connection_;
respondsToSelector:@selector(peerConnection: if (peer_connection == nil) {
didChangeStandardizedIceConnectionState:)]) { return;
}
id<RTC_OBJC_TYPE(RTCPeerConnectionDelegate)> delegate =
peer_connection.delegate;
if (delegate == nil) {
return;
}
if ([delegate respondsToSelector:@selector
(peerConnection:didChangeStandardizedIceConnectionState:)]) {
RTCIceConnectionState state = [RTC_OBJC_TYPE(RTCPeerConnection) RTCIceConnectionState state = [RTC_OBJC_TYPE(RTCPeerConnection)
iceConnectionStateForNativeState:new_state]; iceConnectionStateForNativeState:new_state];
[peer_connection_.delegate peerConnection:peer_connection_ [delegate peerConnection:peer_connection
didChangeStandardizedIceConnectionState:state]; didChangeStandardizedIceConnectionState:state];
} }
} }
void PeerConnectionDelegateAdapter::OnConnectionChange( void PeerConnectionDelegateAdapter::OnConnectionChange(
PeerConnectionInterface::PeerConnectionState new_state) { PeerConnectionInterface::PeerConnectionState new_state) {
if ([peer_connection_.delegate respondsToSelector:@selector RTC_OBJC_TYPE(RTCPeerConnection) *peer_connection = peer_connection_;
(peerConnection:didChangeConnectionState:)]) { if (peer_connection == nil) {
return;
}
id<RTC_OBJC_TYPE(RTCPeerConnectionDelegate)> delegate =
peer_connection.delegate;
if (delegate == nil) {
return;
}
if ([delegate respondsToSelector:@selector(peerConnection:
didChangeConnectionState:)]) {
RTCPeerConnectionState state = [RTC_OBJC_TYPE(RTCPeerConnection) RTCPeerConnectionState state = [RTC_OBJC_TYPE(RTCPeerConnection)
connectionStateForNativeState:new_state]; connectionStateForNativeState:new_state];
[peer_connection_.delegate peerConnection:peer_connection_ [delegate peerConnection:peer_connection didChangeConnectionState:state];
didChangeConnectionState:state];
} }
} }
void PeerConnectionDelegateAdapter::OnIceGatheringChange( void PeerConnectionDelegateAdapter::OnIceGatheringChange(
PeerConnectionInterface::IceGatheringState new_state) { PeerConnectionInterface::IceGatheringState new_state) {
RTC_OBJC_TYPE(RTCPeerConnection) *peer_connection = peer_connection_;
if (peer_connection == nil) {
return;
}
id<RTC_OBJC_TYPE(RTCPeerConnectionDelegate)> delegate =
peer_connection.delegate;
if (delegate == nil) {
return;
}
RTCIceGatheringState state = [[RTC_OBJC_TYPE(RTCPeerConnection) class] RTCIceGatheringState state = [[RTC_OBJC_TYPE(RTCPeerConnection) class]
iceGatheringStateForNativeState:new_state]; iceGatheringStateForNativeState:new_state];
RTC_OBJC_TYPE(RTCPeerConnection) *peer_connection = peer_connection_; [delegate peerConnection:peer_connection didChangeIceGatheringState:state];
[peer_connection.delegate peerConnection:peer_connection
didChangeIceGatheringState:state];
} }
void PeerConnectionDelegateAdapter::OnIceCandidate( void PeerConnectionDelegateAdapter::OnIceCandidate(
const IceCandidateInterface *candidate) { const IceCandidateInterface *candidate) {
RTC_OBJC_TYPE(RTCPeerConnection) *peer_connection = peer_connection_;
if (peer_connection == nil) {
return;
}
id<RTC_OBJC_TYPE(RTCPeerConnectionDelegate)> delegate =
peer_connection.delegate;
if (delegate == nil) {
return;
}
RTC_OBJC_TYPE(RTCIceCandidate) *iceCandidate = RTC_OBJC_TYPE(RTCIceCandidate) *iceCandidate =
[[RTC_OBJC_TYPE(RTCIceCandidate) alloc] [[RTC_OBJC_TYPE(RTCIceCandidate) alloc]
initWithNativeCandidate:candidate]; initWithNativeCandidate:candidate];
RTC_OBJC_TYPE(RTCPeerConnection) *peer_connection = peer_connection_; [delegate peerConnection:peer_connection
[peer_connection.delegate peerConnection:peer_connection didGenerateIceCandidate:iceCandidate];
didGenerateIceCandidate:iceCandidate];
} }
void PeerConnectionDelegateAdapter::OnIceCandidateError( void PeerConnectionDelegateAdapter::OnIceCandidateError(
@ -248,6 +333,14 @@ void PeerConnectionDelegateAdapter::OnIceCandidateError(
int error_code, int error_code,
const std::string &error_text) { const std::string &error_text) {
RTC_OBJC_TYPE(RTCPeerConnection) *peer_connection = peer_connection_; RTC_OBJC_TYPE(RTCPeerConnection) *peer_connection = peer_connection_;
if (peer_connection == nil) {
return;
}
id<RTC_OBJC_TYPE(RTCPeerConnectionDelegate)> delegate =
peer_connection.delegate;
if (delegate == nil) {
return;
}
RTC_OBJC_TYPE(RTCIceCandidateErrorEvent) *event = RTC_OBJC_TYPE(RTCIceCandidateErrorEvent) *event =
[[RTC_OBJC_TYPE(RTCIceCandidateErrorEvent) alloc] [[RTC_OBJC_TYPE(RTCIceCandidateErrorEvent) alloc]
initWithAddress:address initWithAddress:address
@ -255,16 +348,23 @@ void PeerConnectionDelegateAdapter::OnIceCandidateError(
url:url url:url
errorCode:error_code errorCode:error_code
errorText:error_text]; errorText:error_text];
if ([peer_connection.delegate if ([delegate respondsToSelector:@selector(peerConnection:
respondsToSelector:@selector(peerConnection: didFailToGatherIceCandidate:)]) {
didFailToGatherIceCandidate:)]) { [delegate peerConnection:peer_connection didFailToGatherIceCandidate:event];
[peer_connection.delegate peerConnection:peer_connection
didFailToGatherIceCandidate:event];
} }
} }
void PeerConnectionDelegateAdapter::OnIceCandidatesRemoved( void PeerConnectionDelegateAdapter::OnIceCandidatesRemoved(
const std::vector<cricket::Candidate> &candidates) { const std::vector<cricket::Candidate> &candidates) {
RTC_OBJC_TYPE(RTCPeerConnection) *peer_connection = peer_connection_;
if (peer_connection == nil) {
return;
}
id<RTC_OBJC_TYPE(RTCPeerConnectionDelegate)> delegate =
peer_connection.delegate;
if (delegate == nil) {
return;
}
NSMutableArray *ice_candidates = NSMutableArray *ice_candidates =
[NSMutableArray arrayWithCapacity:candidates.size()]; [NSMutableArray arrayWithCapacity:candidates.size()];
for (const auto &candidate : candidates) { for (const auto &candidate : candidates) {
@ -275,13 +375,21 @@ void PeerConnectionDelegateAdapter::OnIceCandidatesRemoved(
initWithNativeCandidate:&candidate_wrapper]; initWithNativeCandidate:&candidate_wrapper];
[ice_candidates addObject:ice_candidate]; [ice_candidates addObject:ice_candidate];
} }
RTC_OBJC_TYPE(RTCPeerConnection) *peer_connection = peer_connection_; [delegate peerConnection:peer_connection
[peer_connection.delegate peerConnection:peer_connection didRemoveIceCandidates:ice_candidates];
didRemoveIceCandidates:ice_candidates];
} }
void PeerConnectionDelegateAdapter::OnIceSelectedCandidatePairChanged( void PeerConnectionDelegateAdapter::OnIceSelectedCandidatePairChanged(
const cricket::CandidatePairChangeEvent &event) { const cricket::CandidatePairChangeEvent &event) {
RTC_OBJC_TYPE(RTCPeerConnection) *peer_connection = peer_connection_;
if (peer_connection == nil) {
return;
}
id<RTC_OBJC_TYPE(RTCPeerConnectionDelegate)> delegate =
peer_connection.delegate;
if (delegate == nil) {
return;
}
const auto &selected_pair = event.selected_candidate_pair; const auto &selected_pair = event.selected_candidate_pair;
JsepIceCandidate local_candidate_wrapper( JsepIceCandidate local_candidate_wrapper(
selected_pair.local_candidate().transport_name(), selected_pair.local_candidate().transport_name(),
@ -297,18 +405,16 @@ void PeerConnectionDelegateAdapter::OnIceSelectedCandidatePairChanged(
RTC_OBJC_TYPE(RTCIceCandidate) *remote_candidate = RTC_OBJC_TYPE(RTCIceCandidate) *remote_candidate =
[[RTC_OBJC_TYPE(RTCIceCandidate) alloc] [[RTC_OBJC_TYPE(RTCIceCandidate) alloc]
initWithNativeCandidate:&remote_candidate_wrapper]; initWithNativeCandidate:&remote_candidate_wrapper];
RTC_OBJC_TYPE(RTCPeerConnection) *peer_connection = peer_connection_;
NSString *nsstr_reason = [NSString stringForStdString:event.reason]; NSString *nsstr_reason = [NSString stringForStdString:event.reason];
if ([peer_connection.delegate if ([delegate respondsToSelector:@selector
respondsToSelector:@selector (peerConnection:
(peerConnection: didChangeLocalCandidate:remoteCandidate:lastReceivedMs
didChangeLocalCandidate:remoteCandidate:lastReceivedMs :changeReason:)]) {
:changeReason:)]) { [delegate peerConnection:peer_connection
[peer_connection.delegate peerConnection:peer_connection didChangeLocalCandidate:local_candidate
didChangeLocalCandidate:local_candidate remoteCandidate:remote_candidate
remoteCandidate:remote_candidate lastReceivedMs:event.last_data_received_ms
lastReceivedMs:event.last_data_received_ms changeReason:nsstr_reason];
changeReason:nsstr_reason];
} }
} }
@ -316,8 +422,17 @@ void PeerConnectionDelegateAdapter::OnAddTrack(
rtc::scoped_refptr<RtpReceiverInterface> receiver, rtc::scoped_refptr<RtpReceiverInterface> receiver,
const std::vector<rtc::scoped_refptr<MediaStreamInterface>> &streams) { const std::vector<rtc::scoped_refptr<MediaStreamInterface>> &streams) {
RTC_OBJC_TYPE(RTCPeerConnection) *peer_connection = peer_connection_; RTC_OBJC_TYPE(RTCPeerConnection) *peer_connection = peer_connection_;
if ([peer_connection.delegate respondsToSelector:@selector if (peer_connection == nil) {
(peerConnection:didAddReceiver:streams:)]) { return;
}
id<RTC_OBJC_TYPE(RTCPeerConnectionDelegate)> delegate =
peer_connection.delegate;
if (delegate == nil) {
return;
}
if ([delegate respondsToSelector:@selector(peerConnection:
didAddReceiver:streams:)]) {
NSMutableArray *mediaStreams = NSMutableArray *mediaStreams =
[NSMutableArray arrayWithCapacity:streams.size()]; [NSMutableArray arrayWithCapacity:streams.size()];
for (const auto &nativeStream : streams) { for (const auto &nativeStream : streams) {
@ -331,22 +446,29 @@ void PeerConnectionDelegateAdapter::OnAddTrack(
alloc] initWithFactory:peer_connection.factory alloc] initWithFactory:peer_connection.factory
nativeRtpReceiver:receiver]; nativeRtpReceiver:receiver];
[peer_connection.delegate peerConnection:peer_connection [delegate peerConnection:peer_connection
didAddReceiver:rtpReceiver didAddReceiver:rtpReceiver
streams:mediaStreams]; streams:mediaStreams];
} }
} }
void PeerConnectionDelegateAdapter::OnRemoveTrack( void PeerConnectionDelegateAdapter::OnRemoveTrack(
rtc::scoped_refptr<RtpReceiverInterface> receiver) { rtc::scoped_refptr<RtpReceiverInterface> receiver) {
RTC_OBJC_TYPE(RTCPeerConnection) *peer_connection = peer_connection_; RTC_OBJC_TYPE(RTCPeerConnection) *peer_connection = peer_connection_;
if ([peer_connection.delegate if (peer_connection == nil) {
respondsToSelector:@selector(peerConnection:didRemoveReceiver:)]) { return;
}
id<RTC_OBJC_TYPE(RTCPeerConnectionDelegate)> delegate =
peer_connection.delegate;
if (delegate == nil) {
return;
}
if ([delegate respondsToSelector:@selector(peerConnection:
didRemoveReceiver:)]) {
RTC_OBJC_TYPE(RTCRtpReceiver) *rtpReceiver = [[RTC_OBJC_TYPE(RTCRtpReceiver) RTC_OBJC_TYPE(RTCRtpReceiver) *rtpReceiver = [[RTC_OBJC_TYPE(RTCRtpReceiver)
alloc] initWithFactory:peer_connection.factory alloc] initWithFactory:peer_connection.factory
nativeRtpReceiver:receiver]; nativeRtpReceiver:receiver];
[peer_connection.delegate peerConnection:peer_connection [delegate peerConnection:peer_connection didRemoveReceiver:rtpReceiver];
didRemoveReceiver:rtpReceiver];
} }
} }