Bug 1595936: Part 2 - Refresh feature policy when attaching browsing context. r=farre,baku
We go to great lengths to try to avoid initializing FrameLoaders during document updates. That means that when `BindToTree` is called, the element's FrameLoader is not initialized, and it has no BrowsingContext. Calling `GetBrowsingContext()` (which happens as a side-effect of `HTMLIFrameElement::RefreshFeaturePolicy`), however, forces eager initialization, which can cause any number of problems. This patch moves that logic from being triggered by `BindToTree` to being triggered by `BrowsingContext::Embed`, which happens as soon as the BrowsingContext is bound to the element, but does not force it to be created early. Differential Revision: https://phabricator.services.mozilla.com/D55872
This commit is contained in:
@@ -15,6 +15,7 @@
|
||||
#include "mozilla/dom/ContentParent.h"
|
||||
#include "mozilla/dom/Document.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
#include "mozilla/dom/HTMLIFrameElement.h"
|
||||
#include "mozilla/dom/Location.h"
|
||||
#include "mozilla/dom/LocationBinding.h"
|
||||
#include "mozilla/dom/PopupBlocker.h"
|
||||
@@ -322,6 +323,12 @@ void BrowsingContext::SetEmbedderElement(Element* aEmbedder) {
|
||||
mEmbedderElement = aEmbedder;
|
||||
}
|
||||
|
||||
void BrowsingContext::Embed() {
|
||||
if (auto* frame = HTMLIFrameElement::FromNode(mEmbedderElement)) {
|
||||
frame->BindToBrowsingContext(this);
|
||||
}
|
||||
}
|
||||
|
||||
void BrowsingContext::Attach(bool aFromIPC) {
|
||||
MOZ_LOG(GetLog(), LogLevel::Debug,
|
||||
("%s: Connecting 0x%08" PRIx64 " to 0x%08" PRIx64,
|
||||
|
||||
@@ -188,6 +188,11 @@ class BrowsingContext : public nsISupports, public nsWrapperCache {
|
||||
Element* GetEmbedderElement() const { return mEmbedderElement; }
|
||||
void SetEmbedderElement(Element* aEmbedder);
|
||||
|
||||
// Called after the BrowingContext has been embedded in a FrameLoader. This
|
||||
// happens after `SetEmbedderElement` is called on the BrowsingContext and
|
||||
// after the BrowsingContext has been set on the FrameLoader.
|
||||
void Embed();
|
||||
|
||||
// Get the outer window object for this BrowsingContext if it is in-process
|
||||
// and still has a docshell, or null otherwise.
|
||||
nsPIDOMWindowOuter* GetDOMWindow() const {
|
||||
|
||||
@@ -2012,6 +2012,7 @@ nsresult nsFrameLoader::MaybeCreateDocShell() {
|
||||
mDocShell = docShell;
|
||||
|
||||
mBrowsingContext->SetEmbedderElement(mOwnerContent);
|
||||
mBrowsingContext->Embed();
|
||||
|
||||
mIsTopLevelContent =
|
||||
mBrowsingContext->IsContent() && !mBrowsingContext->GetParent();
|
||||
@@ -2633,6 +2634,8 @@ bool nsFrameLoader::TryRemoteBrowserInternal() {
|
||||
return false;
|
||||
}
|
||||
|
||||
mRemoteBrowser->GetBrowsingContext()->Embed();
|
||||
|
||||
// Grab the reference to the actor
|
||||
RefPtr<BrowserParent> browserParent = GetBrowserParent();
|
||||
|
||||
@@ -2792,6 +2795,7 @@ nsresult nsFrameLoader::CreateStaticClone(nsFrameLoader* aDest) {
|
||||
|
||||
// Ensure that the embedder element is set correctly.
|
||||
aDest->mBrowsingContext->SetEmbedderElement(aDest->mOwnerContent);
|
||||
aDest->mBrowsingContext->Embed();
|
||||
aDest->mStaticCloneOf = this;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@@ -66,17 +66,11 @@ HTMLIFrameElement::~HTMLIFrameElement() {}
|
||||
|
||||
NS_IMPL_ELEMENT_CLONE(HTMLIFrameElement)
|
||||
|
||||
nsresult HTMLIFrameElement::BindToTree(BindContext& aContext,
|
||||
nsINode& aParent) {
|
||||
nsresult rv = nsGenericHTMLFrameElement::BindToTree(aContext, aParent);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
void HTMLIFrameElement::BindToBrowsingContext(
|
||||
BrowsingContext* aBrowsingContext) {
|
||||
if (StaticPrefs::dom_security_featurePolicy_enabled()) {
|
||||
RefreshFeaturePolicy(true /* parse the feature policy attribute */);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
bool HTMLIFrameElement::ParseAttribute(int32_t aNamespaceID, nsAtom* aAttribute,
|
||||
|
||||
@@ -34,7 +34,6 @@ class HTMLIFrameElement final : public nsGenericHTMLFrameElement {
|
||||
}
|
||||
|
||||
// nsIContent
|
||||
virtual nsresult BindToTree(BindContext&, nsINode& aParent) override;
|
||||
virtual bool ParseAttribute(int32_t aNamespaceID, nsAtom* aAttribute,
|
||||
const nsAString& aValue,
|
||||
nsIPrincipal* aMaybeScriptedPrincipal,
|
||||
@@ -45,6 +44,8 @@ class HTMLIFrameElement final : public nsGenericHTMLFrameElement {
|
||||
|
||||
virtual nsresult Clone(dom::NodeInfo*, nsINode** aResult) const override;
|
||||
|
||||
void BindToBrowsingContext(BrowsingContext* aBrowsingContext);
|
||||
|
||||
uint32_t GetSandboxFlags() const;
|
||||
|
||||
// Web IDL binding methods
|
||||
|
||||
Reference in New Issue
Block a user