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 706822 78073667ddc6e932408f49076b74c448a74bb710
parent 706821 b9b2895b11a32f3da0f4c8fe364bf3bdfc7defb6
child 706823 8994162ee112a8c0a0b33f3404f04ebd9fad1285
push id91936
push userbmo:emilio@crisal.io
push dateMon, 04 Dec 2017 10:24:39 +0000
reviewersbillm
bugs1397426
milestone59.0a1
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