diff --git a/sdk/objc/api/peerconnection/RTCPeerConnection.mm b/sdk/objc/api/peerconnection/RTCPeerConnection.mm index 05fe581d08..67d0ff0cd6 100644 --- a/sdk/objc/api/peerconnection/RTCPeerConnection.mm +++ b/sdk/objc/api/peerconnection/RTCPeerConnection.mm @@ -437,20 +437,18 @@ - (void)addIceCandidate:(RTC_OBJC_TYPE(RTCIceCandidate) *)candidate { - (void)addIceCandidate:(RTC_OBJC_TYPE(RTCIceCandidate) *)candidate completionHandler:(void (^)(NSError *_Nullable error))completionHandler { RTC_DCHECK(completionHandler != nil); - auto iceCandidate = webrtc::CreateIceCandidate(candidate.nativeCandidate->sdp_mid(), - candidate.nativeCandidate->sdp_mline_index(), - candidate.nativeCandidate->candidate()); - _peerConnection->AddIceCandidate(std::move(iceCandidate), [completionHandler](const auto &error) { - if (error.ok()) { - completionHandler(nil); - } else { - NSString *str = [NSString stringForStdString:error.message()]; - NSError *err = [NSError errorWithDomain:kRTCPeerConnectionErrorDomain - code:static_cast(error.type()) - userInfo:@{NSLocalizedDescriptionKey : str}]; - completionHandler(err); - } - }); + _peerConnection->AddIceCandidate( + candidate.nativeCandidate, [completionHandler](const auto &error) { + if (error.ok()) { + completionHandler(nil); + } else { + NSString *str = [NSString stringForStdString:error.message()]; + NSError *err = [NSError errorWithDomain:kRTCPeerConnectionErrorDomain + code:static_cast(error.type()) + userInfo:@{NSLocalizedDescriptionKey : str}]; + completionHandler(err); + } + }); } - (void)removeIceCandidates:(NSArray *)iceCandidates { std::vector candidates; @@ -581,7 +579,7 @@ - (void)setLocalDescription:(RTC_OBJC_TYPE(RTCSessionDescription) *)sdp RTC_DCHECK(completionHandler != nil); rtc::scoped_refptr observer( new rtc::RefCountedObject<::SetSessionDescriptionObserver>(completionHandler)); - _peerConnection->SetLocalDescription(sdp.nativeDescription->Clone(), observer); + _peerConnection->SetLocalDescription(sdp.nativeDescription, observer); } - (void)setLocalDescriptionWithCompletionHandler: @@ -597,7 +595,7 @@ - (void)setRemoteDescription:(RTC_OBJC_TYPE(RTCSessionDescription) *)sdp RTC_DCHECK(completionHandler != nil); rtc::scoped_refptr observer( new rtc::RefCountedObject<::SetSessionDescriptionObserver>(completionHandler)); - _peerConnection->SetRemoteDescription(sdp.nativeDescription->Clone(), observer); + _peerConnection->SetRemoteDescription(sdp.nativeDescription, observer); } - (BOOL)setBweMinBitrateBps:(nullable NSNumber *)minBitrateBps diff --git a/sdk/objc/api/peerconnection/RTCSessionDescription+Private.h b/sdk/objc/api/peerconnection/RTCSessionDescription+Private.h index 0f0a06a887..aa087e557f 100644 --- a/sdk/objc/api/peerconnection/RTCSessionDescription+Private.h +++ b/sdk/objc/api/peerconnection/RTCSessionDescription+Private.h @@ -22,7 +22,8 @@ NS_ASSUME_NONNULL_BEGIN * RTCSessionDescription object. This is needed to pass to the underlying C++ * APIs. */ - @property(nonatomic, readonly, nullable) webrtc::SessionDescriptionInterface *nativeDescription; + @property(nonatomic, + readonly) std::unique_ptr nativeDescription; /** * Initialize an RTCSessionDescription from a native diff --git a/sdk/objc/api/peerconnection/RTCSessionDescription.mm b/sdk/objc/api/peerconnection/RTCSessionDescription.mm index 9fd97fee23..4ff02e8411 100644 --- a/sdk/objc/api/peerconnection/RTCSessionDescription.mm +++ b/sdk/objc/api/peerconnection/RTCSessionDescription.mm @@ -46,13 +46,11 @@ - (NSString *)description { #pragma mark - Private -- (webrtc::SessionDescriptionInterface *)nativeDescription { +- (std::unique_ptr)nativeDescription { webrtc::SdpParseError error; - webrtc::SessionDescriptionInterface *description = - webrtc::CreateSessionDescription([[self class] stdStringForType:_type], - _sdp.stdString, - &error); + std::unique_ptr description(webrtc::CreateSessionDescription( + [[self class] stdStringForType:_type], _sdp.stdString, &error)); if (!description) { RTCLogError(@"Failed to create session description: %s\nline: %s", diff --git a/sdk/objc/unittests/RTCPeerConnectionTest.mm b/sdk/objc/unittests/RTCPeerConnectionTest.mm index e45ca93a6c..1d0ae2679e 100644 --- a/sdk/objc/unittests/RTCPeerConnectionTest.mm +++ b/sdk/objc/unittests/RTCPeerConnectionTest.mm @@ -18,16 +18,20 @@ #import "api/peerconnection/RTCConfiguration+Private.h" #import "api/peerconnection/RTCConfiguration.h" #import "api/peerconnection/RTCCryptoOptions.h" +#import "api/peerconnection/RTCIceCandidate.h" #import "api/peerconnection/RTCIceServer.h" #import "api/peerconnection/RTCMediaConstraints.h" #import "api/peerconnection/RTCPeerConnection.h" #import "api/peerconnection/RTCPeerConnectionFactory+Native.h" #import "api/peerconnection/RTCPeerConnectionFactory.h" +#import "api/peerconnection/RTCSessionDescription.h" #import "helpers/NSString+StdString.h" @interface RTCPeerConnectionTest : NSObject - (void)testConfigurationGetter; - (void)testWithDependencies; +- (void)testWithInvalidSDP; +- (void)testWithInvalidIceCandidate; @end @implementation RTCPeerConnectionTest @@ -137,6 +141,66 @@ - (void)testWithDependencies { } } +- (void)testWithInvalidSDP { + RTC_OBJC_TYPE(RTCPeerConnectionFactory) *factory = + [[RTC_OBJC_TYPE(RTCPeerConnectionFactory) alloc] init]; + + RTC_OBJC_TYPE(RTCConfiguration) *config = [[RTC_OBJC_TYPE(RTCConfiguration) alloc] init]; + RTC_OBJC_TYPE(RTCMediaConstraints) *contraints = + [[RTC_OBJC_TYPE(RTCMediaConstraints) alloc] initWithMandatoryConstraints:@{} + optionalConstraints:nil]; + RTC_OBJC_TYPE(RTCPeerConnection) *peerConnection = + [factory peerConnectionWithConfiguration:config constraints:contraints delegate:nil]; + + dispatch_semaphore_t negotiatedSem = dispatch_semaphore_create(0); + [peerConnection setRemoteDescription:[[RTC_OBJC_TYPE(RTCSessionDescription) alloc] + initWithType:RTCSdpTypeOffer + sdp:@"invalid"] + completionHandler:^(NSError *error) { + ASSERT_NE(error, nil); + if (error != nil) { + dispatch_semaphore_signal(negotiatedSem); + } + }]; + + NSTimeInterval timeout = 5; + ASSERT_EQ( + 0, + dispatch_semaphore_wait(negotiatedSem, + dispatch_time(DISPATCH_TIME_NOW, (int64_t)(timeout * NSEC_PER_SEC)))); + [peerConnection close]; +} + +- (void)testWithInvalidIceCandidate { + RTC_OBJC_TYPE(RTCPeerConnectionFactory) *factory = + [[RTC_OBJC_TYPE(RTCPeerConnectionFactory) alloc] init]; + + RTC_OBJC_TYPE(RTCConfiguration) *config = [[RTC_OBJC_TYPE(RTCConfiguration) alloc] init]; + RTC_OBJC_TYPE(RTCMediaConstraints) *contraints = + [[RTC_OBJC_TYPE(RTCMediaConstraints) alloc] initWithMandatoryConstraints:@{} + optionalConstraints:nil]; + RTC_OBJC_TYPE(RTCPeerConnection) *peerConnection = + [factory peerConnectionWithConfiguration:config constraints:contraints delegate:nil]; + + dispatch_semaphore_t negotiatedSem = dispatch_semaphore_create(0); + [peerConnection addIceCandidate:[[RTC_OBJC_TYPE(RTCIceCandidate) alloc] initWithSdp:@"invalid" + sdpMLineIndex:-1 + sdpMid:nil] + completionHandler:^(NSError *error) { + ASSERT_NE(error, nil); + if (error != nil) { + dispatch_semaphore_signal(negotiatedSem); + } + }]; + + NSTimeInterval timeout = 5; + ASSERT_EQ( + 0, + dispatch_semaphore_wait(negotiatedSem, + dispatch_time(DISPATCH_TIME_NOW, (int64_t)(timeout * NSEC_PER_SEC)))); + [peerConnection close]; +} + @end TEST(RTCPeerConnectionTest, ConfigurationGetterTest) { @@ -152,3 +216,17 @@ - (void)testWithDependencies { [test testWithDependencies]; } } + +TEST(RTCPeerConnectionTest, TestWithInvalidSDP) { + @autoreleasepool { + RTCPeerConnectionTest *test = [[RTCPeerConnectionTest alloc] init]; + [test testWithInvalidSDP]; + } +} + +TEST(RTCPeerConnectionTest, TestWithInvalidIceCandidate) { + @autoreleasepool { + RTCPeerConnectionTest *test = [[RTCPeerConnectionTest alloc] init]; + [test testWithInvalidIceCandidate]; + } +} diff --git a/sdk/objc/unittests/RTCSessionDescriptionTest.mm b/sdk/objc/unittests/RTCSessionDescriptionTest.mm index ee65649cbc..25d7ffe67d 100644 --- a/sdk/objc/unittests/RTCSessionDescriptionTest.mm +++ b/sdk/objc/unittests/RTCSessionDescriptionTest.mm @@ -31,7 +31,7 @@ - (void)testSessionDescriptionConversion { RTC_OBJC_TYPE(RTCSessionDescription) *description = [[RTC_OBJC_TYPE(RTCSessionDescription) alloc] initWithType:RTCSdpTypeAnswer sdp:[self sdp]]; - webrtc::SessionDescriptionInterface *nativeDescription = + std::unique_ptr nativeDescription = description.nativeDescription; EXPECT_EQ(RTCSdpTypeAnswer,