Title: [202749] trunk/Source/WebCore
Revision
202749
Author
[email protected]
Date
2016-07-01 13:31:18 -0700 (Fri, 01 Jul 2016)

Log Message

HTMLMediaElement::resume() may cause _javascript_ execution
https://bugs.webkit.org/show_bug.cgi?id=159327
<rdar://problem/27131641>

Reviewed by Jer Noble.

HTMLMediaElement::updatePlayState can cause an element to begin playing and enter fullscreen,
which can result in a call to the media controls and _javascript_ execution. _javascript_ is not
allowed allowed to run when a page resumes, so make the call to updatePlayState asynchronous.

No new tests, I wasn't able to create a test that triggers the crash.

* html/HTMLMediaElement.cpp:
(WebCore::HTMLMediaElement::scheduleDelayedAction): Support UpdatePlayState.
(WebCore::HTMLMediaElement::pendingActionTimerFired): Ditto.
(WebCore::HTMLMediaElement::setReadyState): UpdateMediaState -> UpdateState.
(WebCore::HTMLMediaElement::playInternal): Don't call updateMediaController, it is called
  by updatePlayState.
(WebCore::HTMLMediaElement::setMuted): UpdateMediaState -> UpdateState.
(WebCore::HTMLMediaElement::mediaPlayerTimeChanged): Ditto.
(WebCore::HTMLMediaElement::mediaEngineWasUpdated): Update media state asynchronously.
(WebCore::HTMLMediaElement::updatePlayState): Add parameter to allow update to happen
  asynchronously.
(WebCore::HTMLMediaElement::setPlaying): UpdateMediaState -> UpdateState.
(WebCore::HTMLMediaElement::setPausedInternal): Update media state asynchronously.
(WebCore::HTMLMediaElement::mediaPlayerCurrentPlaybackTargetIsWirelessChanged):  
  UpdateMediaState -> UpdateState.
(WebCore::HTMLMediaElement::removeEventListener): Ditto.
(WebCore::HTMLMediaElement::enqueuePlaybackTargetAvailabilityChangedEvent): Ditto.
(WebCore::HTMLMediaElement::updateMediaState): UpdateMediaState -> UpdateState
* html/HTMLMediaElement.h:
* html/HTMLMediaElementEnums.h: Add UpdatePlayState.

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (202748 => 202749)


--- trunk/Source/WebCore/ChangeLog	2016-07-01 19:41:30 UTC (rev 202748)
+++ trunk/Source/WebCore/ChangeLog	2016-07-01 20:31:18 UTC (rev 202749)
@@ -1,3 +1,38 @@
+2016-07-01  Eric Carlson  <[email protected]>
+
+        HTMLMediaElement::resume() may cause _javascript_ execution
+        https://bugs.webkit.org/show_bug.cgi?id=159327
+        <rdar://problem/27131641>
+
+        Reviewed by Jer Noble.
+
+        HTMLMediaElement::updatePlayState can cause an element to begin playing and enter fullscreen,
+        which can result in a call to the media controls and _javascript_ execution. _javascript_ is not
+        allowed allowed to run when a page resumes, so make the call to updatePlayState asynchronous.
+
+        No new tests, I wasn't able to create a test that triggers the crash.
+
+        * html/HTMLMediaElement.cpp:
+        (WebCore::HTMLMediaElement::scheduleDelayedAction): Support UpdatePlayState.
+        (WebCore::HTMLMediaElement::pendingActionTimerFired): Ditto.
+        (WebCore::HTMLMediaElement::setReadyState): UpdateMediaState -> UpdateState.
+        (WebCore::HTMLMediaElement::playInternal): Don't call updateMediaController, it is called
+          by updatePlayState.
+        (WebCore::HTMLMediaElement::setMuted): UpdateMediaState -> UpdateState.
+        (WebCore::HTMLMediaElement::mediaPlayerTimeChanged): Ditto.
+        (WebCore::HTMLMediaElement::mediaEngineWasUpdated): Update media state asynchronously.
+        (WebCore::HTMLMediaElement::updatePlayState): Add parameter to allow update to happen
+          asynchronously.
+        (WebCore::HTMLMediaElement::setPlaying): UpdateMediaState -> UpdateState.
+        (WebCore::HTMLMediaElement::setPausedInternal): Update media state asynchronously.
+        (WebCore::HTMLMediaElement::mediaPlayerCurrentPlaybackTargetIsWirelessChanged):  
+          UpdateMediaState -> UpdateState.
+        (WebCore::HTMLMediaElement::removeEventListener): Ditto.
+        (WebCore::HTMLMediaElement::enqueuePlaybackTargetAvailabilityChangedEvent): Ditto.
+        (WebCore::HTMLMediaElement::updateMediaState): UpdateMediaState -> UpdateState
+        * html/HTMLMediaElement.h:
+        * html/HTMLMediaElementEnums.h: Add UpdatePlayState.
+
 2016-07-01  Brady Eidson  <[email protected]>
 
         Blob content type not preserved when retrieving blobs from IndexedDB.

Modified: trunk/Source/WebCore/html/HTMLMediaElement.cpp (202748 => 202749)


--- trunk/Source/WebCore/html/HTMLMediaElement.cpp	2016-07-01 19:41:30 UTC (rev 202748)
+++ trunk/Source/WebCore/html/HTMLMediaElement.cpp	2016-07-01 20:31:18 UTC (rev 202749)
@@ -892,6 +892,9 @@
     if (actionType & MediaEngineUpdated)
         setFlags(m_pendingActionFlags, MediaEngineUpdated);
 
+    if (actionType & UpdatePlayState)
+        setFlags(m_pendingActionFlags, UpdatePlayState);
+
     m_pendingActionTimer.startOneShot(0);
 }
 
@@ -979,6 +982,9 @@
 
     if (pendingActions & MediaEngineUpdated)
         mediaEngineWasUpdated();
+
+    if (pendingActions & UpdatePlayState)
+        updatePlayState();
 }
 
 MediaError* HTMLMediaElement::error() const
@@ -2269,7 +2275,7 @@
         logMediaLoadRequest(document().page(), m_player->engineDescription(), String(), true);
 
 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
-        updateMediaState(UpdateMediaState::Asynchronously);
+        updateMediaState(UpdateState::Asynchronously);
 #endif
 
         m_mediaSession->clientCharacteristicsChanged();
@@ -3126,7 +3132,7 @@
 
     m_autoplaying = false;
     updatePlayState();
-    updateMediaController();
+
     return true;
 }
 
@@ -3358,7 +3364,7 @@
 #endif
 
 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
-        updateMediaState(UpdateMediaState::Asynchronously);
+        updateMediaState(UpdateState::Asynchronously);
 #endif
     }
 
@@ -4418,7 +4424,7 @@
         m_sentEndEvent = false;
     }
 
-    updatePlayState();
+    updatePlayState(UpdateState::Asynchronously);
     endProcessingMediaPlayerCallback();
 }
 
@@ -4594,7 +4600,7 @@
 #endif
 
 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
-    updateMediaState(UpdateMediaState::Asynchronously);
+    updateMediaState(UpdateState::Asynchronously);
 #endif
 }
 
@@ -4828,8 +4834,13 @@
 #endif
 }
 
-void HTMLMediaElement::updatePlayState()
+void HTMLMediaElement::updatePlayState(UpdateState updateState)
 {
+    if (updateState == UpdateState::Asynchronously) {
+        scheduleDelayedAction(UpdatePlayState);
+        return;
+    }
+
     if (!m_player)
         return;
 
@@ -4922,7 +4933,7 @@
 #endif
 
 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
-    updateMediaState(UpdateMediaState::Asynchronously);
+    updateMediaState(UpdateState::Asynchronously);
 #endif
 }
 
@@ -4929,7 +4940,7 @@
 void HTMLMediaElement::setPausedInternal(bool b)
 {
     m_pausedInternal = b;
-    updatePlayState();
+    updatePlayState(UpdateState::Asynchronously);
 }
 
 void HTMLMediaElement::stopPeriodicTimers()
@@ -5221,7 +5232,7 @@
     m_mediaSession->isPlayingToWirelessPlaybackTargetChanged(m_isPlayingToWirelessTarget);
     if (m_isPlayingToWirelessTarget)
         m_mediaSession->setCanProduceAudio(true);
-    updateMediaState(UpdateMediaState::Asynchronously);
+    updateMediaState(UpdateState::Asynchronously);
 }
 
 bool HTMLMediaElement::dispatchEvent(Event& event)
@@ -5266,7 +5277,7 @@
     if (didRemoveLastAvailabilityChangedListener) {
         m_hasPlaybackTargetAvailabilityListeners = false;
         m_mediaSession->setHasPlaybackTargetAvailabilityListeners(*this, false);
-        updateMediaState(UpdateMediaState::Asynchronously);
+        updateMediaState(UpdateState::Asynchronously);
     }
 
     return true;
@@ -5279,7 +5290,7 @@
     auto event = WebKitPlaybackTargetAvailabilityEvent::create(eventNames().webkitplaybacktargetavailabilitychangedEvent, hasTargets);
     event->setTarget(this);
     m_asyncEventQueue.enqueueEvent(WTFMove(event));
-    updateMediaState(UpdateMediaState::Asynchronously);
+    updateMediaState(UpdateState::Asynchronously);
 }
 
 void HTMLMediaElement::setWirelessPlaybackTarget(Ref<MediaPlaybackTarget>&& device)
@@ -6844,9 +6855,9 @@
 }
 
 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
-void HTMLMediaElement::updateMediaState(UpdateMediaState updateState)
+void HTMLMediaElement::updateMediaState(UpdateState updateState)
 {
-    if (updateState == UpdateMediaState::Asynchronously) {
+    if (updateState == UpdateState::Asynchronously) {
         scheduleDelayedAction(CheckMediaState);
         return;
     }

Modified: trunk/Source/WebCore/html/HTMLMediaElement.h (202748 => 202749)


--- trunk/Source/WebCore/html/HTMLMediaElement.h	2016-07-01 19:41:30 UTC (rev 202748)
+++ trunk/Source/WebCore/html/HTMLMediaElement.h	2016-07-01 20:31:18 UTC (rev 202749)
@@ -690,8 +690,10 @@
     void beginProcessingMediaPlayerCallback() { ++m_processingMediaPlayerCallback; }
     void endProcessingMediaPlayerCallback() { ASSERT(m_processingMediaPlayerCallback); --m_processingMediaPlayerCallback; }
 
+    enum class UpdateState { Asynchronously, Synchronously };
+
+    void updatePlayState(UpdateState updateState = UpdateState::Synchronously);
     void updateVolume();
-    void updatePlayState();
     void setPlaying(bool);
     bool potentiallyPlaying() const;
     bool endedPlayback() const;
@@ -770,8 +772,7 @@
     void prepareForDocumentSuspension() final;
     void resumeFromDocumentSuspension() final;
 
-    enum class UpdateMediaState { Asynchronously, Synchronously };
-    void updateMediaState(UpdateMediaState updateState = UpdateMediaState::Synchronously);
+    void updateMediaState(UpdateState updateState = UpdateState::Synchronously);
     bool hasPlaybackTargetAvailabilityListeners() const { return m_hasPlaybackTargetAvailabilityListeners; }
 #endif
 

Modified: trunk/Source/WebCore/html/HTMLMediaElementEnums.h (202748 => 202749)


--- trunk/Source/WebCore/html/HTMLMediaElementEnums.h	2016-07-01 19:41:30 UTC (rev 202748)
+++ trunk/Source/WebCore/html/HTMLMediaElementEnums.h	2016-07-01 20:31:18 UTC (rev 202749)
@@ -42,8 +42,9 @@
         CheckPlaybackTargetCompatablity = 1 << 4,
         CheckMediaState = 1 << 5,
         MediaEngineUpdated = 1 << 6,
+        UpdatePlayState = 1 << 7,
 
-        EveryDelayedAction = LoadMediaResource | ConfigureTextTracks | TextTrackChangesNotification | ConfigureTextTrackDisplay | CheckPlaybackTargetCompatablity | CheckMediaState,
+        EveryDelayedAction = LoadMediaResource | ConfigureTextTracks | TextTrackChangesNotification | ConfigureTextTrackDisplay | CheckPlaybackTargetCompatablity | CheckMediaState | UpdatePlayState,
     };
 
     enum ReadyState { HAVE_NOTHING, HAVE_METADATA, HAVE_CURRENT_DATA, HAVE_FUTURE_DATA, HAVE_ENOUGH_DATA };
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to