Bug 1589054 - Part 2: Delay pagehide events until new nsFrameLoader is set up, r=farre

If these are fired too early, a nested event loop can be spun before the new
nsFrameLoader has been set up. Messages can be received over the
BrowserBridgeChild actor during this time when no nsFrameLoader is set, causing
crashes.

Differential Revision: https://phabricator.services.mozilla.com/D49647

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Nika Layzell 2019-10-22 13:57:00 +00:00
Родитель a3cad4162e
Коммит bc9c3bb08c
1 изменённых файлов: 33 добавлений и 25 удалений

Просмотреть файл

@ -90,34 +90,42 @@ void nsFrameLoaderOwner::ChangeRemotenessCommon(
doc->BlockOnload();
auto cleanup = MakeScopeExit([&]() { doc->UnblockOnload(false); });
// If we already have a Frameloader, destroy it, possibly preserving its
// browsing context.
if (mFrameLoader) {
if (aPreserveContext) {
bc = mFrameLoader->GetBrowsingContext();
mFrameLoader->SkipBrowsingContextDetach();
{
// Introduce a script blocker to ensure no JS is executed during the
// nsFrameLoader teardown & recreation process. Unload listeners will be run
// for the previous document, and the load will be started for the new one,
// at the end of this block.
nsAutoScriptBlocker sb;
// If we already have a Frameloader, destroy it, possibly preserving its
// browsing context.
if (mFrameLoader) {
if (aPreserveContext) {
bc = mFrameLoader->GetBrowsingContext();
mFrameLoader->SkipBrowsingContextDetach();
}
// Preserve the networkCreated status, as nsDocShells created after a
// process swap may shouldn't change their dynamically-created status.
networkCreated = mFrameLoader->IsNetworkCreated();
mFrameLoader->Destroy();
mFrameLoader = nullptr;
}
// Preserve the networkCreated status, as nsDocShells created after a
// process swap may shouldn't change their dynamically-created status.
networkCreated = mFrameLoader->IsNetworkCreated();
mFrameLoader->Destroy();
mFrameLoader = nullptr;
}
mFrameLoader =
nsFrameLoader::Recreate(owner, bc, aRemoteType, networkCreated);
if (NS_WARN_IF(!mFrameLoader)) {
aRv.Throw(NS_ERROR_FAILURE);
return;
}
mFrameLoader =
nsFrameLoader::Recreate(owner, bc, aRemoteType, networkCreated);
if (NS_WARN_IF(!mFrameLoader)) {
aRv.Throw(NS_ERROR_FAILURE);
return;
}
// Invoke the frame loader initialization callback to perform setup on our new
// nsFrameLoader. This may cause our ErrorResult to become errored, so
// double-check after calling.
aFrameLoaderInit();
if (NS_WARN_IF(aRv.Failed())) {
return;
// Invoke the frame loader initialization callback to perform setup on our
// new nsFrameLoader. This may cause our ErrorResult to become errored, so
// double-check after calling.
aFrameLoaderInit();
if (NS_WARN_IF(aRv.Failed())) {
return;
}
}
// Now that we've got a new FrameLoader, we need to reset our