Changeset 202749 in webkit


Ignore:
Timestamp:
Jul 1, 2016 1:31:18 PM (8 years ago)
Author:
eric.carlson@apple.com
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.
Location:
trunk/Source/WebCore
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r202747 r202749  
     12016-07-01  Eric Carlson  <eric.carlson@apple.com>
     2
     3        HTMLMediaElement::resume() may cause JavaScript execution
     4        https://bugs.webkit.org/show_bug.cgi?id=159327
     5        <rdar://problem/27131641>
     6
     7        Reviewed by Jer Noble.
     8
     9        HTMLMediaElement::updatePlayState can cause an element to begin playing and enter fullscreen,
     10        which can result in a call to the media controls and JavaScript execution. Javascript is not
     11        allowed allowed to run when a page resumes, so make the call to updatePlayState asynchronous.
     12
     13        No new tests, I wasn't able to create a test that triggers the crash.
     14
     15        * html/HTMLMediaElement.cpp:
     16        (WebCore::HTMLMediaElement::scheduleDelayedAction): Support UpdatePlayState.
     17        (WebCore::HTMLMediaElement::pendingActionTimerFired): Ditto.
     18        (WebCore::HTMLMediaElement::setReadyState): UpdateMediaState -> UpdateState.
     19        (WebCore::HTMLMediaElement::playInternal): Don't call updateMediaController, it is called
     20          by updatePlayState.
     21        (WebCore::HTMLMediaElement::setMuted): UpdateMediaState -> UpdateState.
     22        (WebCore::HTMLMediaElement::mediaPlayerTimeChanged): Ditto.
     23        (WebCore::HTMLMediaElement::mediaEngineWasUpdated): Update media state asynchronously.
     24        (WebCore::HTMLMediaElement::updatePlayState): Add parameter to allow update to happen
     25          asynchronously.
     26        (WebCore::HTMLMediaElement::setPlaying): UpdateMediaState -> UpdateState.
     27        (WebCore::HTMLMediaElement::setPausedInternal): Update media state asynchronously.
     28        (WebCore::HTMLMediaElement::mediaPlayerCurrentPlaybackTargetIsWirelessChanged): 
     29          UpdateMediaState -> UpdateState.
     30        (WebCore::HTMLMediaElement::removeEventListener): Ditto.
     31        (WebCore::HTMLMediaElement::enqueuePlaybackTargetAvailabilityChangedEvent): Ditto.
     32        (WebCore::HTMLMediaElement::updateMediaState): UpdateMediaState -> UpdateState
     33        * html/HTMLMediaElement.h:
     34        * html/HTMLMediaElementEnums.h: Add UpdatePlayState.
     35
    1362016-07-01  Brady Eidson  <beidson@apple.com>
    237
  • trunk/Source/WebCore/html/HTMLMediaElement.cpp

    r202427 r202749  
    893893        setFlags(m_pendingActionFlags, MediaEngineUpdated);
    894894
     895    if (actionType & UpdatePlayState)
     896        setFlags(m_pendingActionFlags, UpdatePlayState);
     897
    895898    m_pendingActionTimer.startOneShot(0);
    896899}
     
    980983    if (pendingActions & MediaEngineUpdated)
    981984        mediaEngineWasUpdated();
     985
     986    if (pendingActions & UpdatePlayState)
     987        updatePlayState();
    982988}
    983989
     
    22702276
    22712277#if ENABLE(WIRELESS_PLAYBACK_TARGET)
    2272         updateMediaState(UpdateMediaState::Asynchronously);
     2278        updateMediaState(UpdateState::Asynchronously);
    22732279#endif
    22742280
     
    31273133    m_autoplaying = false;
    31283134    updatePlayState();
    3129     updateMediaController();
     3135
    31303136    return true;
    31313137}
     
    33593365
    33603366#if ENABLE(WIRELESS_PLAYBACK_TARGET)
    3361         updateMediaState(UpdateMediaState::Asynchronously);
     3367        updateMediaState(UpdateState::Asynchronously);
    33623368#endif
    33633369    }
     
    44194425    }
    44204426
    4421     updatePlayState();
     4427    updatePlayState(UpdateState::Asynchronously);
    44224428    endProcessingMediaPlayerCallback();
    44234429}
     
    45954601
    45964602#if ENABLE(WIRELESS_PLAYBACK_TARGET)
    4597     updateMediaState(UpdateMediaState::Asynchronously);
     4603    updateMediaState(UpdateState::Asynchronously);
    45984604#endif
    45994605}
     
    48294835}
    48304836
    4831 void HTMLMediaElement::updatePlayState()
    4832 {
     4837void HTMLMediaElement::updatePlayState(UpdateState updateState)
     4838{
     4839    if (updateState == UpdateState::Asynchronously) {
     4840        scheduleDelayedAction(UpdatePlayState);
     4841        return;
     4842    }
     4843
    48334844    if (!m_player)
    48344845        return;
     
    49234934
    49244935#if ENABLE(WIRELESS_PLAYBACK_TARGET)
    4925     updateMediaState(UpdateMediaState::Asynchronously);
     4936    updateMediaState(UpdateState::Asynchronously);
    49264937#endif
    49274938}
     
    49304941{
    49314942    m_pausedInternal = b;
    4932     updatePlayState();
     4943    updatePlayState(UpdateState::Asynchronously);
    49334944}
    49344945
     
    52225233    if (m_isPlayingToWirelessTarget)
    52235234        m_mediaSession->setCanProduceAudio(true);
    5224     updateMediaState(UpdateMediaState::Asynchronously);
     5235    updateMediaState(UpdateState::Asynchronously);
    52255236}
    52265237
     
    52675278        m_hasPlaybackTargetAvailabilityListeners = false;
    52685279        m_mediaSession->setHasPlaybackTargetAvailabilityListeners(*this, false);
    5269         updateMediaState(UpdateMediaState::Asynchronously);
     5280        updateMediaState(UpdateState::Asynchronously);
    52705281    }
    52715282
     
    52805291    event->setTarget(this);
    52815292    m_asyncEventQueue.enqueueEvent(WTFMove(event));
    5282     updateMediaState(UpdateMediaState::Asynchronously);
     5293    updateMediaState(UpdateState::Asynchronously);
    52835294}
    52845295
     
    68456856
    68466857#if ENABLE(WIRELESS_PLAYBACK_TARGET)
    6847 void HTMLMediaElement::updateMediaState(UpdateMediaState updateState)
    6848 {
    6849     if (updateState == UpdateMediaState::Asynchronously) {
     6858void HTMLMediaElement::updateMediaState(UpdateState updateState)
     6859{
     6860    if (updateState == UpdateState::Asynchronously) {
    68506861        scheduleDelayedAction(CheckMediaState);
    68516862        return;
  • trunk/Source/WebCore/html/HTMLMediaElement.h

    r202183 r202749  
    691691    void endProcessingMediaPlayerCallback() { ASSERT(m_processingMediaPlayerCallback); --m_processingMediaPlayerCallback; }
    692692
     693    enum class UpdateState { Asynchronously, Synchronously };
     694
     695    void updatePlayState(UpdateState updateState = UpdateState::Synchronously);
    693696    void updateVolume();
    694     void updatePlayState();
    695697    void setPlaying(bool);
    696698    bool potentiallyPlaying() const;
     
    771773    void resumeFromDocumentSuspension() final;
    772774
    773     enum class UpdateMediaState { Asynchronously, Synchronously };
    774     void updateMediaState(UpdateMediaState updateState = UpdateMediaState::Synchronously);
     775    void updateMediaState(UpdateState updateState = UpdateState::Synchronously);
    775776    bool hasPlaybackTargetAvailabilityListeners() const { return m_hasPlaybackTargetAvailabilityListeners; }
    776777#endif
  • trunk/Source/WebCore/html/HTMLMediaElementEnums.h

    r199126 r202749  
    4343        CheckMediaState = 1 << 5,
    4444        MediaEngineUpdated = 1 << 6,
     45        UpdatePlayState = 1 << 7,
    4546
    46         EveryDelayedAction = LoadMediaResource | ConfigureTextTracks | TextTrackChangesNotification | ConfigureTextTrackDisplay | CheckPlaybackTargetCompatablity | CheckMediaState,
     47        EveryDelayedAction = LoadMediaResource | ConfigureTextTracks | TextTrackChangesNotification | ConfigureTextTrackDisplay | CheckPlaybackTargetCompatablity | CheckMediaState | UpdatePlayState,
    4748    };
    4849
Note: See TracChangeset for help on using the changeset viewer.