Bug 1631405 - Make sure we initialize all fields of WindowGlobalParent in the constructor. r=nika

Previously we only set some fields as part of WindowGlobalInit, but WindowGlobalParent sets itself as the current window global on the CanonicalBrowsingContext.

This exposes a period of time where only part of the document state was set, and this was observable to consumers.

This makes OnNewDocument only run when there is a new Document for the same WindowGlobal.

Differential Revision: https://phabricator.services.mozilla.com/D75446
This commit is contained in:
Matt Woodrow 2020-05-26 21:15:42 +00:00
parent 67c0d914f3
commit 5b64e9bae2
14 changed files with 102 additions and 14 deletions

View File

@ -16,6 +16,7 @@ namespace dom {
class WindowGlobalParent;
class WindowGlobalInit;
class BrowsingContextGroup;
#define MOZ_EACH_WC_FIELD(FIELD) \
FIELD(CookieBehavior, Maybe<uint32_t>) \

View File

@ -2401,10 +2401,13 @@ nsresult nsGlobalWindowOuter::SetNewDocument(Document* aDocument,
newInnerWindow->mChromeEventHandler = mChromeEventHandler;
}
if (!aState) {
if (!aState && reUseInnerWindow) {
// Notify our WindowGlobalChild that it has a new document. If `aState` was
// passed, we're restoring the window from the BFCache, so the document
// hasn't changed.
// If we didn't have a window global child before, then initializing
// it will have set all the required state, so we don't need to do
// it again.
mInnerWindow->GetWindowGlobalChild()->OnNewDocument(aDocument);
}

View File

@ -16,6 +16,7 @@
#include "mozilla/dom/Promise.h"
#include "mozilla/dom/URL.h"
#include "mozilla/dom/WorkerPrivate.h"
#include "mozilla/dom/WindowContext.h"
#include "mozilla/Unused.h"
namespace mozilla {

View File

@ -10,6 +10,7 @@
#include "mozilla/dom/PBrowserBridgeParent.h"
#include "mozilla/Tuple.h"
#include "mozilla/dom/ipc/IdType.h"
#include "mozilla/dom/WindowGlobalTypes.h"
namespace mozilla {

View File

@ -41,7 +41,6 @@ using refcounted class nsIReferrerInfo from "mozilla/dom/ReferrerInfoUtils.h";
using refcounted class nsIVariant from "mozilla/dom/PropertyBagUtils.h";
using class mozilla::TimeStamp from "mozilla/TimeStamp.h";
using refcounted class mozilla::dom::BrowsingContext from "mozilla/dom/BrowsingContext.h";
using mozilla::dom::WindowContextInitializer from "mozilla/dom/WindowContext.h";
namespace mozilla {
namespace dom {
@ -229,17 +228,6 @@ struct PerformanceInfo
CategoryDispatch[] items;
};
struct WindowGlobalInit
{
// Fields which are synchronized to other processes are found here.
WindowContextInitializer context;
// Private fields only shared with the parent process.
nsIPrincipal principal;
nsIPrincipal contentBlockingAllowListPrincipal;
nsIURI documentURI;
};
struct DocShellLoadStateInit
{
nsIURI URI;

View File

@ -22,6 +22,7 @@ include protocol PWindowGlobal;
include protocol PBrowserBridge;
include DOMTypes;
include WindowGlobalTypes;
include IPCBlob;
include IPCStream;
include URIParams;

View File

@ -47,6 +47,7 @@ include protocol PScriptCache;
include protocol PSessionStorageObserver;
include protocol PBenchmarkStorage;
include DOMTypes;
include WindowGlobalTypes;
include IPCBlob;
include IPCStream;
include PTabContext;

View File

@ -13,6 +13,7 @@
#include "mozilla/dom/JSActorService.h"
#include "mozilla/dom/JSWindowActorParent.h"
#include "mozilla/dom/JSWindowActorChild.h"
#include "mozilla/net/CookieJarSettings.h"
namespace mozilla {
namespace dom {
@ -85,6 +86,54 @@ WindowGlobalInit WindowGlobalActor::WindowInitializer(
aWindow->GetDocumentContentBlockingAllowListPrincipal();
init.documentURI() = aWindow->GetDocumentURI();
Document* doc = aWindow->GetDocument();
init.blockAllMixedContent() = doc->GetBlockAllMixedContent(false);
init.upgradeInsecureRequests() = doc->GetUpgradeInsecureRequests(false);
init.sandboxFlags() = doc->GetSandboxFlags();
net::CookieJarSettings::Cast(doc->CookieJarSettings())
->Serialize(init.cookieJarSettings());
mozilla::Get<WindowContext::IDX_CookieBehavior>(init.context().mFields) =
Some(doc->CookieJarSettings()->GetCookieBehavior());
mozilla::Get<WindowContext::IDX_IsOnContentBlockingAllowList>(
init.context().mFields) =
doc->CookieJarSettings()->GetIsOnContentBlockingAllowList();
mozilla::Get<WindowContext::IDX_IsThirdPartyWindow>(init.context().mFields) =
nsContentUtils::IsThirdPartyWindowOrChannel(aWindow, nullptr, nullptr);
mozilla::Get<WindowContext::IDX_IsThirdPartyTrackingResourceWindow>(
init.context().mFields) =
nsContentUtils::IsThirdPartyTrackingResourceWindow(aWindow);
mozilla::Get<WindowContext::IDX_IsSecureContext>(init.context().mFields) =
aWindow->IsSecureContext();
auto policy = doc->GetEmbedderPolicyFromHTTP();
if (policy.isSome()) {
mozilla::Get<WindowContext::IDX_EmbedderPolicy>(init.context().mFields) =
policy.ref();
}
// Init Mixed Content Fields
nsCOMPtr<nsIURI> innerDocURI = NS_GetInnermostURI(doc->GetDocumentURI());
if (innerDocURI) {
mozilla::Get<WindowContext::IDX_IsSecure>(init.context().mFields) =
innerDocURI->SchemeIs("https");
}
nsCOMPtr<nsIChannel> mixedChannel;
aWindow->GetDocShell()->GetMixedContentChannel(getter_AddRefs(mixedChannel));
// A non null mixedContent channel on the docshell indicates,
// that the user has overriden mixed content to allow mixed
// content loads to happen.
if (mixedChannel && (mixedChannel == doc->GetChannel())) {
mozilla::Get<WindowContext::IDX_AllowMixedContent>(init.context().mFields) =
true;
}
// Most data here is specific to the Document, which can change without
// creating a new WindowGlobal. Anything new added here which fits that
// description should also be synchronized in
// WindowGlobalChild::OnNewDocument.
return init;
}

View File

@ -14,6 +14,7 @@
#include "nsIURI.h"
#include "nsString.h"
#include "mozilla/dom/JSActor.h"
#include "mozilla/dom/WindowGlobalTypes.h"
namespace mozilla {
namespace dom {

View File

@ -158,7 +158,10 @@ void WindowGlobalChild::OnNewDocument(Document* aDocument) {
MOZ_RELEASE_ASSERT(aDocument);
// Send a series of messages to update document-specific state on
// WindowGlobalParent.
// WindowGlobalParent, when we change documents on an existing WindowGlobal.
// This data is also all sent when we construct a WindowGlobal, so anything
// added here should also be added to WindowGlobalActor::WindowInitializer.
// FIXME: Perhaps these should be combined into a smaller number of messages?
SetDocumentURI(aDocument->GetDocumentURI());
SetDocumentPrincipal(aDocument->NodePrincipal());

View File

@ -90,6 +90,11 @@ already_AddRefed<WindowGlobalParent> WindowGlobalParent::CreateDisconnected(
wgp->mDocumentURI = aInit.documentURI();
wgp->mDocContentBlockingAllowListPrincipal =
aInit.contentBlockingAllowListPrincipal();
wgp->mBlockAllMixedContent = aInit.blockAllMixedContent();
wgp->mUpgradeInsecureRequests = aInit.upgradeInsecureRequests();
wgp->mSandboxFlags = aInit.sandboxFlags();
net::CookieJarSettings::Deserialize(aInit.cookieJarSettings(),
getter_AddRefs(wgp->mCookieJarSettings));
MOZ_RELEASE_ASSERT(wgp->mDocumentPrincipal, "Must have a valid principal");
return wgp.forget();

View File

@ -0,0 +1,32 @@
/* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 8 -*- */
/* vim: set sw=4 ts=8 et tw=80 ft=cpp : */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
include NeckoChannelParams;
include DOMTypes;
using mozilla::dom::WindowContextInitializer from "mozilla/dom/WindowContext.h";
namespace mozilla {
namespace dom {
struct WindowGlobalInit
{
// Fields which are synchronized to other processes are found here.
WindowContextInitializer context;
// Private fields only shared with the parent process.
nsIPrincipal principal;
nsIPrincipal contentBlockingAllowListPrincipal;
nsIURI documentURI;
bool blockAllMixedContent;
bool upgradeInsecureRequests;
uint32_t sandboxFlags;
CookieJarSettingsArgs cookieJarSettings;
};
} // namespace dom
} // namespace mozilla

View File

@ -174,6 +174,7 @@ IPDL_SOURCES += [
'PURLClassifierLocal.ipdl',
'PWindowGlobal.ipdl',
'ServiceWorkerConfiguration.ipdlh',
'WindowGlobalTypes.ipdlh',
]
include('/ipc/chromium/chromium-config.mozbuild')

View File

@ -41,6 +41,7 @@
#include "mozilla/dom/TimeoutHandler.h"
#include "mozilla/dom/WorkerBinding.h"
#include "mozilla/dom/JSExecutionManager.h"
#include "mozilla/dom/WindowContext.h"
#include "mozilla/StorageAccess.h"
#include "mozilla/StoragePrincipalHelper.h"
#include "mozilla/ThreadEventQueue.h"