Bug 1490012 - FlushPendingMediaFeatureValuesChanged can kill the PresShell. r=xidorn a=pascalc
authorEmilio Cobos Álvarez <emilio@crisal.io>
Tue, 11 Sep 2018 15:35:36 +0200
changeset 489851 f09bf04f488c
parent 489850 ec22c8843396
child 489852 808461b7530b
push id9802
push userncsoregi@mozilla.com
push dateFri, 14 Sep 2018 19:50:13 +0000
treeherdermozilla-beta@dd935a08ff4a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersxidorn, pascalc
bugs1490012
milestone63.0
Bug 1490012 - FlushPendingMediaFeatureValuesChanged can kill the PresShell. r=xidorn a=pascalc It can flush the parent document from MediaQueryList::RecomputeMatches, which can destroy our pres context. I think that flush is wrong btw, it should probably either flush layout so the viewport size is correct, or just not flush (we should make MediaList::Matches take a document now that we don't need a pres context to match media queries, but that requires a bit more refactoring). Differential Revision: https://phabricator.services.mozilla.com/D5524
layout/base/PresShell.cpp
layout/style/crashtests/1490012.html
layout/style/crashtests/crashtests.list
--- a/layout/base/PresShell.cpp
+++ b/layout/base/PresShell.cpp
@@ -4260,20 +4260,22 @@ PresShell::DoFlushPendingNotifications(m
     // construct frames for content right now that's still waiting to be
     // notified on,
     mDocument->FlushPendingNotifications(FlushType::ContentAndNotify);
 
     mDocument->UpdateSVGUseElementShadowTrees();
 
     // Process pending restyles, since any flush of the presshell wants
     // up-to-date style data.
-    if (!mIsDestroying) {
+    if (MOZ_LIKELY(!mIsDestroying)) {
       viewManager->FlushDelayedResize(false);
       mPresContext->FlushPendingMediaFeatureValuesChanged();
-
+    }
+
+    if (MOZ_LIKELY(!mIsDestroying)) {
       // Now that we have flushed media queries, update the rules before looking
       // up @font-face / @counter-style / @font-feature-values rules.
       mStyleSet->UpdateStylistIfNeeded();
 
       // Flush any pending update of the user font set, since that could
       // cause style changes (for updating ex/ch units, and to cause a
       // reflow).
       mDocument->FlushUserFontSet();
@@ -4285,43 +4287,43 @@ PresShell::DoFlushPendingNotifications(m
       // Flush any requested SMIL samples.
       if (mDocument->HasAnimationController()) {
         mDocument->GetAnimationController()->FlushResampleRequests();
       }
 
       if (aFlush.mFlushAnimations && mPresContext->EffectCompositor()) {
         mPresContext->EffectCompositor()->PostRestyleForThrottledAnimations();
       }
-
-      // The FlushResampleRequests() above flushed style changes.
-      if (!mIsDestroying) {
-        nsAutoScriptBlocker scriptBlocker;
+    }
+
+    // The FlushResampleRequests() above flushed style changes.
+    if (MOZ_LIKELY(!mIsDestroying)) {
+      nsAutoScriptBlocker scriptBlocker;
 #ifdef MOZ_GECKO_PROFILER
-        AutoProfilerStyleMarker tracingStyleFlush(std::move(mStyleCause));
+      AutoProfilerStyleMarker tracingStyleFlush(std::move(mStyleCause));
 #endif
 
-        mPresContext->RestyleManager()->ProcessPendingRestyles();
-      }
+      mPresContext->RestyleManager()->ProcessPendingRestyles();
     }
 
     // Process whatever XBL constructors those restyles queued up.  This
     // ensures that onload doesn't fire too early and that we won't do extra
     // reflows after those constructors run.
-    if (!mIsDestroying) {
+    if (MOZ_LIKELY(!mIsDestroying)) {
       mDocument->BindingManager()->ProcessAttachedQueue();
     }
 
     // Now those constructors or events might have posted restyle
     // events.  At the same time, we still need up-to-date style data.
     // In particular, reflow depends on style being completely up to
     // date.  If it's not, then style reparenting, which can
     // happen during reflow, might suddenly pick up the new rules and
     // we'll end up with frames whose style doesn't match the frame
     // type.
-    if (!mIsDestroying) {
+    if (MOZ_LIKELY(!mIsDestroying)) {
       nsAutoScriptBlocker scriptBlocker;
 #ifdef MOZ_GECKO_PROFILER
       AutoProfilerStyleMarker tracingStyleFlush(std::move(mStyleCause));
 #endif
 
       mPresContext->RestyleManager()->ProcessPendingRestyles();
       // Clear mNeedStyleFlush here agagin to make this flag work properly for
       // optimization since the flag might have set in ProcessPendingRestyles().
new file mode 100644
--- /dev/null
+++ b/layout/style/crashtests/1490012.html
@@ -0,0 +1,11 @@
+<script>
+function go() {
+  b.appendChild(document.createElement("iframe"));
+  a.scroll({left: -1, top: 1});
+  window[0].matchMedia("").addListener(function(){});
+  b.open = false;
+}
+</script>
+<body onload=go()>
+<image id="a"></image>
+<details id="b" open="true">
--- a/layout/style/crashtests/crashtests.list
+++ b/layout/style/crashtests/crashtests.list
@@ -287,8 +287,9 @@ pref(dom.webcomponents.shadowdom.enabled
 load 1454140.html
 load 1455108.html
 load 1457288.html
 load 1457985.html
 pref(dom.webcomponents.shadowdom.enabled,true) load 1468640.html
 load 1469076.html
 load 1475003.html
 load 1479681.html
+load 1490012.html