Crash in WebCore::HTMLMediaElement::detachMediaSource()
authorpeng.liu6@apple.com <peng.liu6@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 27 Jan 2020 20:29:14 +0000 (20:29 +0000)
committerpeng.liu6@apple.com <peng.liu6@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 27 Jan 2020 20:29:14 +0000 (20:29 +0000)
https://bugs.webkit.org/show_bug.cgi?id=206766

Reviewed by Jer Noble.

Use WeakPtr<HTMLMediaElement> in MediaSource instead of a raw pointer.
In addition, we need to detach a MediaSource from an HTMLMediaElement before the HTMLMediaElement forgets the reference to the MediaSource.

* Modules/mediasource/MediaSource.cpp:
(WebCore::MediaSource::attachToElement):
* Modules/mediasource/MediaSource.h:
* html/HTMLMediaElement.cpp:
(WebCore::HTMLMediaElement::loadResource):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@255161 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebCore/ChangeLog
Source/WebCore/Modules/mediasource/MediaSource.cpp
Source/WebCore/Modules/mediasource/MediaSource.h
Source/WebCore/html/HTMLMediaElement.cpp

index d2d3197..dcf8bff 100644 (file)
@@ -1,3 +1,19 @@
+2020-01-27  Peng Liu  <peng.liu6@apple.com>
+
+        Crash in WebCore::HTMLMediaElement::detachMediaSource()
+        https://bugs.webkit.org/show_bug.cgi?id=206766
+
+        Reviewed by Jer Noble.
+
+        Use WeakPtr<HTMLMediaElement> in MediaSource instead of a raw pointer.
+        In addition, we need to detach a MediaSource from an HTMLMediaElement before the HTMLMediaElement forgets the reference to the MediaSource.
+
+        * Modules/mediasource/MediaSource.cpp:
+        (WebCore::MediaSource::attachToElement):
+        * Modules/mediasource/MediaSource.h:
+        * html/HTMLMediaElement.cpp:
+        (WebCore::HTMLMediaElement::loadResource):
+
 2020-01-27  Said Abou-Hallawa  <sabouhallawa@apple.com>
 
         Throttling requestAnimationFrame should be controlled by RenderingUpdateScheduler
index 2a5adb7..4e4193b 100644 (file)
@@ -956,7 +956,7 @@ bool MediaSource::attachToElement(HTMLMediaElement& element)
 
     ASSERT(isClosed());
 
-    m_mediaElement = &element;
+    m_mediaElement = makeWeakPtr(&element);
     return true;
 }
 
index 9278d7a..425bf97 100644 (file)
 #include "EventTarget.h"
 #include "ExceptionOr.h"
 #include "GenericEventQueue.h"
+#include "HTMLMediaElement.h"
 #include "MediaSourcePrivateClient.h"
 #include "URLRegistry.h"
 #include <wtf/LoggerHelper.h>
+#include <wtf/WeakPtr.h>
 
 namespace WebCore {
 
 class ContentType;
-class HTMLMediaElement;
 class SourceBuffer;
 class SourceBufferList;
 class SourceBufferPrivate;
@@ -97,7 +98,7 @@ public:
     ReadyState readyState() const { return m_readyState; }
     ExceptionOr<void> endOfStream(Optional<EndOfStreamError>);
 
-    HTMLMediaElement* mediaElement() const { return m_mediaElement; }
+    HTMLMediaElement* mediaElement() const { return m_mediaElement.get(); }
 
     SourceBufferList* sourceBuffers() { return m_sourceBuffers.get(); }
     SourceBufferList* activeSourceBuffers() { return m_activeSourceBuffers.get(); }
@@ -161,7 +162,7 @@ private:
     RefPtr<SourceBufferList> m_activeSourceBuffers;
     mutable std::unique_ptr<PlatformTimeRanges> m_buffered;
     std::unique_ptr<PlatformTimeRanges> m_liveSeekable;
-    HTMLMediaElement* m_mediaElement { nullptr };
+    WeakPtr<HTMLMediaElement> m_mediaElement;
     MediaTime m_duration;
     MediaTime m_pendingSeekTime;
     ReadyState m_readyState { ReadyState::Closed };
index 357b619..190089e 100644 (file)
@@ -1535,11 +1535,16 @@ void HTMLMediaElement::loadResource(const URL& initialURL, ContentType& contentT
         loadAttempted = true;
 
         ALWAYS_LOG(LOGIDENTIFIER, "loading MSE blob");
-        if (!m_mediaSource->attachToElement(*this) || !m_player->load(url, contentType, m_mediaSource.get())) {
+        if (!m_mediaSource->attachToElement(*this)) {
             // Forget our reference to the MediaSource, so we leave it alone
             // while processing remainder of load failure.
             m_mediaSource = nullptr;
             mediaLoadingFailed(MediaPlayer::NetworkState::FormatError);
+        } else if (!m_player->load(url, contentType, m_mediaSource.get())) {
+            // We have to detach the MediaSource before we forget the reference to it.
+            m_mediaSource->detachFromElement(*this);
+            m_mediaSource = nullptr;
+            mediaLoadingFailed(MediaPlayer::NetworkState::FormatError);
         }
     }
 #endif