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:
Kris Maglione
2020-01-24 19:03:10 +00:00
parent c02232dc88
commit 04adf714ef
5 changed files with 20 additions and 9 deletions

View File

@@ -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,

View File

@@ -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 {

View File

@@ -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;
}

View File

@@ -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,

View File

@@ -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