Bug 1397426 - TabChild::MakeHidden shouldn't cause script to run. r=billm
authorMike Conley <mconley@mozilla.com>
Tue, 21 Nov 2017 16:52:48 -0500
changeset 446484 78073667ddc6e932408f49076b74c448a74bb710
parent 446483 b9b2895b11a32f3da0f4c8fe364bf3bdfc7defb6
child 446485 8994162ee112a8c0a0b33f3404f04ebd9fad1285
push id8527
push userCallek@gmail.com
push dateThu, 11 Jan 2018 21:05:50 +0000
treeherdermozilla-beta@95342d212a7a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbillm
bugs1397426
milestone59.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 1397426 - TabChild::MakeHidden shouldn't cause script to run. r=billm Calling GetPresShell() might create a content viewer, which might cause script to run. This is bad if there's a ForcePaint message queued up, because it could mean running the force painting code while we're still in the midst of making a tab hidden, which would put us in an inconsistent state. MozReview-Commit-ID: 3rw2wGllGdk
dom/ipc/TabChild.cpp
--- a/dom/ipc/TabChild.cpp
+++ b/dom/ipc/TabChild.cpp
@@ -3057,25 +3057,31 @@ TabChild::MakeHidden()
   // it's possible to be told to become hidden before we're finished
   // setting up a layer manager. We should skip clearing cached layers
   // in that case, since doing so might accidentally put is into
   // BasicLayers mode.
   if (mPuppetWidget && mPuppetWidget->HasLayerManager()) {
     ClearCachedResources();
   }
 
-  // Hide all plugins in this tab.
-  if (nsCOMPtr<nsIPresShell> shell = GetPresShell()) {
-    if (nsPresContext* presContext = shell->GetPresContext()) {
-      nsRootPresContext* rootPresContext = presContext->GetRootPresContext();
-      nsIFrame* rootFrame = shell->FrameConstructor()->GetRootFrame();
-      rootPresContext->ComputePluginGeometryUpdates(rootFrame, nullptr, nullptr);
-      rootPresContext->ApplyPluginGeometryUpdates();
+  nsCOMPtr<nsIDocShell> docShell = do_GetInterface(WebNavigation());
+  if (docShell) {
+    // Hide all plugins in this tab. We don't use TabChildBase::GetPresShell()
+    // here because that would create a content viewer if one doesn't exist yet.
+    // Creating a content viewer can cause JS to run, which we want to avoid.
+    // nsIDocShell::GetPresShell returns null if no content viewer exists yet.
+    if (nsCOMPtr<nsIPresShell> presShell = docShell->GetPresShell()) {
+      if (nsPresContext* presContext = presShell->GetPresContext()) {
+        nsRootPresContext* rootPresContext = presContext->GetRootPresContext();
+        nsIFrame* rootFrame = presShell->FrameConstructor()->GetRootFrame();
+        rootPresContext->ComputePluginGeometryUpdates(rootFrame, nullptr, nullptr);
+        rootPresContext->ApplyPluginGeometryUpdates();
+      }
+      presShell->SetIsActive(false);
     }
-    shell->SetIsActive(false);
   }
 
   if (mPuppetWidget) {
     mPuppetWidget->Show(false);
   }
 }
 
 bool