Bug 1421965: Avoid nullptr crash when conduits cannot be created. r?drno draft
authorByron Campen [:bwc] <docfaraday@gmail.com>
Mon, 04 Dec 2017 12:57:26 -0600 (2017-12-04)
changeset 707020 bd55c12c3b39afea5df581b05210529e81e18233
parent 706949 195bb467e6cb5c8c5f5fb2858c0a55b2d0b9552d
child 742842 7ff5faf21047c73ab56e3a9ed633a8fb02486290
push id92006
push userbcampen@mozilla.com
push dateMon, 04 Dec 2017 18:57:41 +0000 (2017-12-04)
reviewersdrno
bugs1421965
milestone59.0a1
Bug 1421965: Avoid nullptr crash when conduits cannot be created. r?drno MozReview-Commit-ID: AdWiIbpFP0Y
media/webrtc/signaling/src/peerconnection/PeerConnectionMedia.cpp
media/webrtc/signaling/src/peerconnection/TransceiverImpl.cpp
media/webrtc/signaling/src/peerconnection/TransceiverImpl.h
--- a/media/webrtc/signaling/src/peerconnection/PeerConnectionMedia.cpp
+++ b/media/webrtc/signaling/src/peerconnection/PeerConnectionMedia.cpp
@@ -1149,16 +1149,20 @@ PeerConnectionMedia::AddTransceiver(
       mParent->GetHandle(),
       aJsepTransceiver,
       mMainThread.get(),
       mSTSThread.get(),
       aReceiveStream,
       aSendTrack,
       mCall.get());
 
+  if (!transceiver->IsValid()) {
+    return NS_ERROR_FAILURE;
+  }
+
   if (aSendTrack) {
     // implement checking for peerIdentity (where failure == black/silence)
     nsIDocument* doc = mParent->GetWindow()->GetExtantDoc();
     if (doc) {
       transceiver->UpdateSinkIdentity(nullptr,
                                       doc->NodePrincipal(),
                                       mParent->GetPeerIdentity());
     } else {
--- a/media/webrtc/signaling/src/peerconnection/TransceiverImpl.cpp
+++ b/media/webrtc/signaling/src/peerconnection/TransceiverImpl.cpp
@@ -51,16 +51,20 @@ TransceiverImpl::TransceiverImpl(
   mCallWrapper(aCallWrapper)
 {
   if (IsVideo()) {
     InitVideo();
   } else {
     InitAudio();
   }
 
+  if (!IsValid()) {
+    return;
+  }
+
   mConduit->SetPCHandle(mPCHandle);
 
   StartReceiveStream();
 
   mTransmitPipeline = new MediaPipelineTransmit(
       mPCHandle,
       mMainThread.get(),
       mStsThread.get(),
@@ -73,29 +77,45 @@ TransceiverImpl::~TransceiverImpl() = de
 
 NS_IMPL_ISUPPORTS0(TransceiverImpl)
 
 void
 TransceiverImpl::InitAudio()
 {
   mConduit = AudioSessionConduit::Create();
 
+  if (!mConduit) {
+    MOZ_MTLOG(ML_ERROR, mPCHandle << "[" << mMid << "]: " << __FUNCTION__ <<
+                        ": Failed to create AudioSessionConduit");
+    // TODO(bug 1422897): We need a way to record this when it happens in the
+    // wild.
+    return;
+  }
+
   mReceivePipeline = new MediaPipelineReceiveAudio(
       mPCHandle,
       mMainThread.get(),
       mStsThread.get(),
       static_cast<AudioSessionConduit*>(mConduit.get()),
       mReceiveStream->GetInputStream()->AsSourceStream());
 }
 
 void
 TransceiverImpl::InitVideo()
 {
   mConduit = VideoSessionConduit::Create(mCallWrapper);
 
+  if (!mConduit) {
+    MOZ_MTLOG(ML_ERROR, mPCHandle << "[" << mMid << "]: " << __FUNCTION__ <<
+                        ": Failed to create VideoSessionConduit");
+    // TODO(bug 1422897): We need a way to record this when it happens in the
+    // wild.
+    return;
+  }
+
   mReceivePipeline = new MediaPipelineReceiveVideo(
       mPCHandle,
       mMainThread.get(),
       mStsThread.get(),
       static_cast<VideoSessionConduit*>(mConduit.get()),
       mReceiveStream->GetInputStream()->AsSourceStream());
 }
 
--- a/media/webrtc/signaling/src/peerconnection/TransceiverImpl.h
+++ b/media/webrtc/signaling/src/peerconnection/TransceiverImpl.h
@@ -53,16 +53,21 @@ public:
   TransceiverImpl(const std::string& aPCHandle,
                   JsepTransceiver* aJsepTransceiver,
                   nsIEventTarget* aMainThread,
                   nsIEventTarget* aStsThread,
                   DOMMediaStream& aReceiveStream,
                   dom::MediaStreamTrack* aSendTrack,
                   WebRtcCallWrapper* aCallWrapper);
 
+  bool IsValid() const
+  {
+    return !!mConduit;
+  }
+
   nsresult UpdateSendTrack(dom::MediaStreamTrack* aSendTrack);
 
   nsresult UpdateSinkIdentity(dom::MediaStreamTrack* aTrack,
                               nsIPrincipal* aPrincipal,
                               const PeerIdentity* aSinkIdentity);
 
   nsresult UpdateTransport(PeerConnectionMedia& aTransportManager);