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
--- 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