From f519d74b3bae650b42deb502babea8babec7c769 Mon Sep 17 00:00:00 2001 From: Eden Chuang Date: Fri, 17 Apr 2020 11:29:13 +0000 Subject: [PATCH] Bug 1598131 - Propagate the browsingContext's COEP to the new created one in nsFrameLoader::Recreate r=farre The COEP header needs to propagate to the new created BrowsingContext for process switching. Differential Revision: https://phabricator.services.mozilla.com/D69936 --- dom/base/nsFrameLoader.cpp | 9 ++++-- dom/base/nsFrameLoader.h | 3 +- dom/base/nsFrameLoaderOwner.cpp | 31 +++++++++++++------ dom/base/nsFrameLoaderOwner.h | 17 +++++++++- .../coep-blob-popup.https.html.ini | 7 ----- .../resources/blank.html.headers | 1 + 6 files changed, 47 insertions(+), 21 deletions(-) create mode 100644 testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/blank.html.headers diff --git a/dom/base/nsFrameLoader.cpp b/dom/base/nsFrameLoader.cpp index 5f4c2986fbe6..c23bd87fedb2 100644 --- a/dom/base/nsFrameLoader.cpp +++ b/dom/base/nsFrameLoader.cpp @@ -413,7 +413,7 @@ already_AddRefed nsFrameLoader::Create( /* static */ already_AddRefed nsFrameLoader::Recreate( mozilla::dom::Element* aOwner, BrowsingContext* aContext, - const nsAString& aRemoteType, bool aNetworkCreated) { + const nsAString& aRemoteType, bool aNetworkCreated, bool aPreserveContext) { NS_ENSURE_TRUE(aOwner, nullptr); #ifdef DEBUG @@ -426,11 +426,16 @@ already_AddRefed nsFrameLoader::Recreate( #endif RefPtr context = aContext; - if (!context) { + if (!context || !aPreserveContext) { context = CreateBrowsingContext(aOwner, /* openWindowInfo */ nullptr); } NS_ENSURE_TRUE(context, nullptr); + // aContext is not preserved, propagate its COEP to the new created. + if (aContext && !aPreserveContext) { + context->SetEmbedderPolicy(aContext->GetEmbedderPolicy()); + } + RefPtr fl = new nsFrameLoader(aOwner, context, aRemoteType, aNetworkCreated); return fl.forget(); diff --git a/dom/base/nsFrameLoader.h b/dom/base/nsFrameLoader.h index cb7984daba61..988eb0212042 100644 --- a/dom/base/nsFrameLoader.h +++ b/dom/base/nsFrameLoader.h @@ -111,7 +111,8 @@ class nsFrameLoader final : public nsStubMutationObserver, static already_AddRefed Recreate(Element* aOwner, BrowsingContext* aContext, const nsAString& aRemoteType, - bool aNetworkCreated); + bool aNetworkCreated, + bool aPreserveContext); NS_DECLARE_STATIC_IID_ACCESSOR(NS_FRAMELOADER_IID) diff --git a/dom/base/nsFrameLoaderOwner.cpp b/dom/base/nsFrameLoaderOwner.cpp index 02f10f54977d..9801faa8f781 100644 --- a/dom/base/nsFrameLoaderOwner.cpp +++ b/dom/base/nsFrameLoaderOwner.cpp @@ -74,9 +74,9 @@ bool nsFrameLoaderOwner::ShouldPreserveBrowsingContext( } void nsFrameLoaderOwner::ChangeRemotenessCommon( - bool aPreserveContext, bool aSwitchingInProgressLoad, - const nsAString& aRemoteType, std::function& aFrameLoaderInit, - mozilla::ErrorResult& aRv) { + const ChangeRemotenessContextType& aContextType, + bool aSwitchingInProgressLoad, const nsAString& aRemoteType, + std::function& aFrameLoaderInit, mozilla::ErrorResult& aRv) { RefPtr bc; bool networkCreated = false; @@ -105,9 +105,11 @@ void nsFrameLoaderOwner::ChangeRemotenessCommon( // If we already have a Frameloader, destroy it, possibly preserving its // browsing context. if (mFrameLoader) { - if (aPreserveContext) { + if (aContextType != ChangeRemotenessContextType::DONT_PRESERVE) { bc = mFrameLoader->GetBrowsingContext(); - mFrameLoader->SetWillChangeProcess(); + if (aContextType == ChangeRemotenessContextType::PRESERVE) { + mFrameLoader->SetWillChangeProcess(); + } } // Preserve the networkCreated status, as nsDocShells created after a @@ -117,8 +119,9 @@ void nsFrameLoaderOwner::ChangeRemotenessCommon( mFrameLoader = nullptr; } - mFrameLoader = - nsFrameLoader::Recreate(owner, bc, aRemoteType, networkCreated); + mFrameLoader = nsFrameLoader::Recreate( + owner, bc, aRemoteType, networkCreated, + aContextType == ChangeRemotenessContextType::PRESERVE); if (NS_WARN_IF(!mFrameLoader)) { aRv.Throw(NS_ERROR_FAILURE); return; @@ -204,8 +207,15 @@ void nsFrameLoaderOwner::ChangeRemoteness( } }; - ChangeRemotenessCommon(ShouldPreserveBrowsingContext(aOptions), - aOptions.mSwitchingInProgressLoad, + ChangeRemotenessContextType preserveType = + ChangeRemotenessContextType::DONT_PRESERVE; + if (ShouldPreserveBrowsingContext(aOptions)) { + preserveType = ChangeRemotenessContextType::PRESERVE; + } else if (aOptions.mReplaceBrowsingContext) { + preserveType = ChangeRemotenessContextType::DONT_PRESERVE_BUT_PROPAGATE; + } + + ChangeRemotenessCommon(preserveType, aOptions.mSwitchingInProgressLoad, aOptions.mRemoteType, frameLoaderInit, rv); } @@ -227,6 +237,7 @@ void nsFrameLoaderOwner::ChangeRemotenessWithBridge(BrowserBridgeChild* aBridge, // NOTE: We always use the DEFAULT_REMOTE_TYPE here, because we don't actually // know the real remote type, and don't need to, as we're a content process. ChangeRemotenessCommon( - /* preserve */ true, /* switching in progress load */ true, + /* preserve */ ChangeRemotenessContextType::PRESERVE, + /* switching in progress load */ true, NS_LITERAL_STRING(DEFAULT_REMOTE_TYPE), frameLoaderInit, rv); } diff --git a/dom/base/nsFrameLoaderOwner.h b/dom/base/nsFrameLoaderOwner.h index 8b7f95324108..4bfcb7ad4d75 100644 --- a/dom/base/nsFrameLoaderOwner.h +++ b/dom/base/nsFrameLoaderOwner.h @@ -60,7 +60,22 @@ class nsFrameLoaderOwner : public nsISupports { bool UseRemoteSubframes(); bool ShouldPreserveBrowsingContext( const mozilla::dom::RemotenessOptions& aOptions); - void ChangeRemotenessCommon(bool aPreserveContext, + + // The enum class for determine how to handle previous BrowsingContext during + // the change remoteness. It could be followings + // 1. DONT_PRESERVE + // Create a whole new BrowsingContext. + // 2. DONT_PRESERVE_BUT_PROPAGETE + // Create a whole new BrowsingContext, but propagate necessary feilds from + // previous BrowsingContext, i.e. COEP. + // 3. PRESERVE + // Preserve the previous BrowsingContext. + enum class ChangeRemotenessContextType { + DONT_PRESERVE = 0, + DONT_PRESERVE_BUT_PROPAGATE = 1, + PRESERVE = 2, + }; + void ChangeRemotenessCommon(const ChangeRemotenessContextType& aContextType, bool aSwitchingInProgressLoad, const nsAString& aRemoteType, std::function& aFrameLoaderInit, diff --git a/testing/web-platform/meta/html/cross-origin-opener-policy/coep-blob-popup.https.html.ini b/testing/web-platform/meta/html/cross-origin-opener-policy/coep-blob-popup.https.html.ini index 15bd10c478d3..6aa9064e8f80 100644 --- a/testing/web-platform/meta/html/cross-origin-opener-policy/coep-blob-popup.https.html.ini +++ b/testing/web-platform/meta/html/cross-origin-opener-policy/coep-blob-popup.https.html.ini @@ -1,10 +1,3 @@ [coep-blob-popup.https.html] [COOP+COEP blob URL popup: ] expected: FAIL - - [COOP+COEP blob URL popup: window.open()] - expected: FAIL - - [COOP+COEP blob URL popup: ] - expected: FAIL - diff --git a/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/blank.html.headers b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/blank.html.headers new file mode 100644 index 000000000000..6604450991a1 --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/blank.html.headers @@ -0,0 +1 @@ +Cross-Origin-Embedder-Policy: require-corp