From c0868a6edb9f3f567946a13bed214d47894243db Mon Sep 17 00:00:00 2001 From: Nika Layzell Date: Tue, 22 Sep 2020 16:28:37 +0000 Subject: [PATCH] Bug 1656753 - Track CrossGroupOpener on CanonicalBrowsingContext, r=farre Differential Revision: https://phabricator.services.mozilla.com/D90890 --- docshell/base/CanonicalBrowsingContext.cpp | 7 +++++++ docshell/base/CanonicalBrowsingContext.h | 9 +++++++++ docshell/base/nsDSURIContentListener.cpp | 16 ++++++---------- docshell/base/nsDSURIContentListener.h | 6 +++--- dom/base/nsFrameLoader.cpp | 8 ++++++++ 5 files changed, 33 insertions(+), 13 deletions(-) diff --git a/docshell/base/CanonicalBrowsingContext.cpp b/docshell/base/CanonicalBrowsingContext.cpp index f9765cf884d3..4993e87cba1c 100644 --- a/docshell/base/CanonicalBrowsingContext.cpp +++ b/docshell/base/CanonicalBrowsingContext.cpp @@ -1461,6 +1461,13 @@ void CanonicalBrowsingContext::HistoryCommitIndexAndLength( }); } +void CanonicalBrowsingContext::SetCrossGroupOpenerId(uint64_t aOpenerId) { + MOZ_DIAGNOSTIC_ASSERT(IsTopContent()); + MOZ_DIAGNOSTIC_ASSERT(mCrossGroupOpenerId == 0, + "Can only set CrossGroupOpenerId once"); + mCrossGroupOpenerId = aOpenerId; +} + NS_IMPL_CYCLE_COLLECTION_INHERITED(CanonicalBrowsingContext, BrowsingContext, mSessionHistory) diff --git a/docshell/base/CanonicalBrowsingContext.h b/docshell/base/CanonicalBrowsingContext.h index 6eb09ff02d99..14378981b259 100644 --- a/docshell/base/CanonicalBrowsingContext.h +++ b/docshell/base/CanonicalBrowsingContext.h @@ -71,6 +71,13 @@ class CanonicalBrowsingContext final : public BrowsingContext { void ClearInFlightProcessId(uint64_t aProcessId); uint64_t GetInFlightProcessId() const { return mInFlightProcessId; } + // The ID of the BrowsingContext which caused this BrowsingContext to be + // opened, or `0` if this is unknown. + // Only set for toplevel content BrowsingContexts, and may be from a different + // BrowsingContextGroup. + uint64_t GetCrossGroupOpenerId() const { return mCrossGroupOpenerId; } + void SetCrossGroupOpenerId(uint64_t aOpenerId); + void GetWindowGlobals(nsTArray>& aWindows); // The current active WindowGlobal. @@ -301,6 +308,8 @@ class CanonicalBrowsingContext final : public BrowsingContext { // have in-flight messages that assume it is still the owner. uint64_t mInFlightProcessId = 0; + uint64_t mCrossGroupOpenerId = 0; + // The current remoteness change which is in a pending state. RefPtr mPendingRemotenessChange; diff --git a/docshell/base/nsDSURIContentListener.cpp b/docshell/base/nsDSURIContentListener.cpp index fa64a7e34fcc..d2f339c9ec81 100644 --- a/docshell/base/nsDSURIContentListener.cpp +++ b/docshell/base/nsDSURIContentListener.cpp @@ -72,24 +72,20 @@ BrowsingContext* MaybeCloseWindowHelper::MaybeCloseWindow() { already_AddRefed MaybeCloseWindowHelper::ChooseNewBrowsingContext(BrowsingContext* aBC) { - RefPtr bc = aBC; - - RefPtr opener = bc->GetOpener(); + RefPtr opener = aBC->GetOpener(); if (opener && !opener->IsDiscarded()) { return opener.forget(); } if (!XRE_IsParentProcess()) { - return bc.forget(); + return nullptr; } - CanonicalBrowsingContext* cbc = CanonicalBrowsingContext::Cast(aBC); - RefPtr wgp = cbc->GetEmbedderWindowGlobal(); - if (!wgp) { - return bc.forget(); + opener = BrowsingContext::Get(aBC->Canonical()->GetCrossGroupOpenerId()); + if (!opener || opener->IsDiscarded()) { + return nullptr; } - - return do_AddRef(wgp->BrowsingContext()); + return opener.forget(); } NS_IMETHODIMP diff --git a/docshell/base/nsDSURIContentListener.h b/docshell/base/nsDSURIContentListener.h index 97c8274b3c0a..a9e7da728ff7 100644 --- a/docshell/base/nsDSURIContentListener.h +++ b/docshell/base/nsDSURIContentListener.h @@ -30,9 +30,9 @@ class MaybeCloseWindowHelper final : public nsITimerCallback { * Closes the provided window async (if mShouldCloseWindow is true) and * returns a valid browsingContext to be used instead as parent for dialogs or * similar things. - * In case mShouldCloseWindow is true, the final browsing context will be the - * a valid new chrome window to use. It can be the opener, or the opener's - * top, or the top chrome window. + * In case mShouldCloseWindow is true, the returned BrowsingContext will be + * the window's opener (or original cross-group opener in the case of a + * `noopener` popup). */ mozilla::dom::BrowsingContext* MaybeCloseWindow(); diff --git a/dom/base/nsFrameLoader.cpp b/dom/base/nsFrameLoader.cpp index b639c0420207..795485b42233 100644 --- a/dom/base/nsFrameLoader.cpp +++ b/dom/base/nsFrameLoader.cpp @@ -414,6 +414,14 @@ already_AddRefed nsFrameLoader::Create( CreateBrowsingContext(aOwner, aOpenWindowInfo, group, aNetworkCreated); NS_ENSURE_TRUE(context, nullptr); + if (XRE_IsParentProcess() && aOpenWindowInfo) { + MOZ_ASSERT(context->IsTopContent()); + if (RefPtr crossGroupOpener = + aOpenWindowInfo->GetParent()) { + context->Canonical()->SetCrossGroupOpenerId(crossGroupOpener->Id()); + } + } + bool isRemoteFrame = InitialLoadIsRemote(aOwner); RefPtr fl = new nsFrameLoader(aOwner, context, isRemoteFrame, aNetworkCreated);