Bug 1490012 - FlushPendingMediaFeatureValuesChanged can kill the PresShell. r=xidorn
authorEmilio Cobos Álvarez <emilio@crisal.io>
Tue, 11 Sep 2018 15:35:36 +0200
changeset 436025 cc1f16ecff46b5daf37154f5d84592e54663bca4
parent 436024 7505dc56eead8f654f19be80a0aa2b7773a05999
child 436026 b499d1183c996ce044961ecf5cd67b139b095427
push id34625
push userdvarga@mozilla.com
push dateThu, 13 Sep 2018 02:31:40 +0000
treeherdermozilla-central@51e9e9660b3e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersxidorn
bugs1490012
milestone64.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1490012 - FlushPendingMediaFeatureValuesChanged can kill the PresShell. r=xidorn 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
@@ -4254,20 +4254,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();
@@ -4279,43 +4281,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