Bug 1921733 - Update load info when object loads get upgraded. r=necko-reviewers,peterv
Differential Revision: https://phabricator.services.mozilla.com/D224956
This commit is contained in:
@@ -218,8 +218,6 @@ already_AddRefed<nsIDocShell> nsObjectLoadingContent::SetupDocShell(
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
MaybeStoreCrossOriginFeaturePolicy();
|
|
||||||
|
|
||||||
return docShell.forget();
|
return docShell.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1554,6 +1552,7 @@ void nsObjectLoadingContent::Destroy() {
|
|||||||
void nsObjectLoadingContent::Traverse(nsObjectLoadingContent* tmp,
|
void nsObjectLoadingContent::Traverse(nsObjectLoadingContent* tmp,
|
||||||
nsCycleCollectionTraversalCallback& cb) {
|
nsCycleCollectionTraversalCallback& cb) {
|
||||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mFrameLoader);
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mFrameLoader);
|
||||||
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mFeaturePolicy);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* static */
|
/* static */
|
||||||
@@ -1562,6 +1561,7 @@ void nsObjectLoadingContent::Unlink(nsObjectLoadingContent* tmp) {
|
|||||||
tmp->mFrameLoader->Destroy();
|
tmp->mFrameLoader->Destroy();
|
||||||
}
|
}
|
||||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mFrameLoader);
|
NS_IMPL_CYCLE_COLLECTION_UNLINK(mFrameLoader);
|
||||||
|
NS_IMPL_CYCLE_COLLECTION_UNLINK(mFeaturePolicy);
|
||||||
}
|
}
|
||||||
|
|
||||||
void nsObjectLoadingContent::UnloadObject(bool aResetState) {
|
void nsObjectLoadingContent::UnloadObject(bool aResetState) {
|
||||||
@@ -1720,6 +1720,13 @@ nsObjectLoadingContent::UpgradeLoadToDocument(
|
|||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// At this point we know that we have a browsing context, so it's time to make
|
||||||
|
// sure that that browsing context gets the correct container feature policy.
|
||||||
|
// This is needed for `DocumentLoadListener::MaybeTriggerProcessSwitch` to be
|
||||||
|
// able to start loading the document with the correct container feature
|
||||||
|
// policy in the load info.
|
||||||
|
RefreshFeaturePolicy();
|
||||||
|
|
||||||
bc.forget(aBrowsingContext);
|
bc.forget(aBrowsingContext);
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
@@ -1818,6 +1825,9 @@ void nsObjectLoadingContent::SubdocumentImageLoadComplete(nsresult aResult) {
|
|||||||
|
|
||||||
void nsObjectLoadingContent::MaybeStoreCrossOriginFeaturePolicy() {
|
void nsObjectLoadingContent::MaybeStoreCrossOriginFeaturePolicy() {
|
||||||
MOZ_DIAGNOSTIC_ASSERT(mFrameLoader);
|
MOZ_DIAGNOSTIC_ASSERT(mFrameLoader);
|
||||||
|
if (!mFrameLoader) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// If the browsingContext is not ready (because docshell is dead), don't try
|
// If the browsingContext is not ready (because docshell is dead), don't try
|
||||||
// to create one.
|
// to create one.
|
||||||
@@ -1831,15 +1841,54 @@ void nsObjectLoadingContent::MaybeStoreCrossOriginFeaturePolicy() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Element* el = AsElement();
|
auto* el = nsGenericHTMLElement::FromNode(AsElement());
|
||||||
if (!el->IsInComposedDoc()) {
|
if (!el->IsInComposedDoc()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
FeaturePolicy* featurePolicy = el->OwnerDoc()->FeaturePolicy();
|
if (ContentChild* cc = ContentChild::GetSingleton()) {
|
||||||
|
|
||||||
if (ContentChild* cc = ContentChild::GetSingleton(); cc && featurePolicy) {
|
|
||||||
Unused << cc->SendSetContainerFeaturePolicy(
|
Unused << cc->SendSetContainerFeaturePolicy(
|
||||||
browsingContext, Some(featurePolicy->ToFeaturePolicyInfo()));
|
browsingContext, Some(mFeaturePolicy->ToFeaturePolicyInfo()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* static */ already_AddRefed<nsIPrincipal>
|
||||||
|
nsObjectLoadingContent::GetFeaturePolicyDefaultOrigin(nsINode* aNode) {
|
||||||
|
auto* el = nsGenericHTMLElement::FromNode(aNode);
|
||||||
|
nsCOMPtr<nsIURI> nodeURI;
|
||||||
|
// Different elements keep this in various locations
|
||||||
|
if (el->NodeInfo()->Equals(nsGkAtoms::object)) {
|
||||||
|
el->GetURIAttr(nsGkAtoms::data, nullptr, getter_AddRefs(nodeURI));
|
||||||
|
} else if (el->NodeInfo()->Equals(nsGkAtoms::embed)) {
|
||||||
|
el->GetURIAttr(nsGkAtoms::src, nullptr, getter_AddRefs(nodeURI));
|
||||||
|
}
|
||||||
|
|
||||||
|
nsCOMPtr<nsIPrincipal> principal;
|
||||||
|
if (nodeURI) {
|
||||||
|
principal = BasePrincipal::CreateContentPrincipal(
|
||||||
|
nodeURI,
|
||||||
|
BasePrincipal::Cast(el->NodePrincipal())->OriginAttributesRef());
|
||||||
|
} else {
|
||||||
|
principal = el->NodePrincipal();
|
||||||
|
}
|
||||||
|
|
||||||
|
return principal.forget();
|
||||||
|
}
|
||||||
|
|
||||||
|
void nsObjectLoadingContent::RefreshFeaturePolicy() {
|
||||||
|
if (mType != ObjectType::Document) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!mFeaturePolicy) {
|
||||||
|
mFeaturePolicy = MakeAndAddRef<FeaturePolicy>(AsElement());
|
||||||
|
}
|
||||||
|
|
||||||
|
// The origin can change if 'src' or 'data' attributes change.
|
||||||
|
nsCOMPtr<nsIPrincipal> origin = GetFeaturePolicyDefaultOrigin(AsElement());
|
||||||
|
MOZ_ASSERT(origin);
|
||||||
|
mFeaturePolicy->SetDefaultOrigin(origin);
|
||||||
|
|
||||||
|
mFeaturePolicy->InheritPolicy(AsElement()->OwnerDoc()->FeaturePolicy());
|
||||||
|
MaybeStoreCrossOriginFeaturePolicy();
|
||||||
|
}
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ class nsFrameLoader;
|
|||||||
|
|
||||||
namespace mozilla::dom {
|
namespace mozilla::dom {
|
||||||
struct BindContext;
|
struct BindContext;
|
||||||
|
class FeaturePolicy;
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class Sequence;
|
class Sequence;
|
||||||
class HTMLIFrameElement;
|
class HTMLIFrameElement;
|
||||||
@@ -213,6 +214,14 @@ class nsObjectLoadingContent : public nsIStreamListener,
|
|||||||
*/
|
*/
|
||||||
bool BlockEmbedOrObjectContentLoading();
|
bool BlockEmbedOrObjectContentLoading();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates and stores the container's feature policy in its canonical browsing
|
||||||
|
* context. This gets called whenever the feature policy has changed, which
|
||||||
|
* can happen when this element is upgraded to a container or when the URI of
|
||||||
|
* the element has changed.
|
||||||
|
*/
|
||||||
|
void RefreshFeaturePolicy();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Object parameter changes returned by UpdateObjectParameters
|
// Object parameter changes returned by UpdateObjectParameters
|
||||||
enum ParameterUpdateFlags {
|
enum ParameterUpdateFlags {
|
||||||
@@ -393,6 +402,14 @@ class nsObjectLoadingContent : public nsIStreamListener,
|
|||||||
*/
|
*/
|
||||||
void MaybeStoreCrossOriginFeaturePolicy();
|
void MaybeStoreCrossOriginFeaturePolicy();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the value of either `data` or `src`, depending on element type,
|
||||||
|
* parsed as a URL. If URL is invalid or the attribute is missing this returns
|
||||||
|
* the document's origin.
|
||||||
|
*/
|
||||||
|
static already_AddRefed<nsIPrincipal> GetFeaturePolicyDefaultOrigin(
|
||||||
|
nsINode* aNode);
|
||||||
|
|
||||||
// The final listener for mChannel (uriloader, pluginstreamlistener, etc.)
|
// The final listener for mChannel (uriloader, pluginstreamlistener, etc.)
|
||||||
nsCOMPtr<nsIStreamListener> mFinalListener;
|
nsCOMPtr<nsIStreamListener> mFinalListener;
|
||||||
|
|
||||||
@@ -464,6 +481,14 @@ class nsObjectLoadingContent : public nsIStreamListener,
|
|||||||
// our own frame.
|
// our own frame.
|
||||||
mozilla::Maybe<mozilla::IntrinsicSize> mSubdocumentIntrinsicSize;
|
mozilla::Maybe<mozilla::IntrinsicSize> mSubdocumentIntrinsicSize;
|
||||||
mozilla::Maybe<mozilla::AspectRatio> mSubdocumentIntrinsicRatio;
|
mozilla::Maybe<mozilla::AspectRatio> mSubdocumentIntrinsicRatio;
|
||||||
|
|
||||||
|
// This gets created on the first call of `RefreshFeaturePolicy`, and will be
|
||||||
|
// kept after that. Navigations of this element will use this if they're
|
||||||
|
// targetting documents, which is how iframe element works. If it's a
|
||||||
|
// non-document the feature policy isn't used, but it doesn't hurt to keep it
|
||||||
|
// around, and a subsequent document load will continue using it after
|
||||||
|
// refreshing it.
|
||||||
|
RefPtr<mozilla::dom::FeaturePolicy> mFeaturePolicy;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -79,6 +79,10 @@ void HTMLEmbedElement::AfterSetAttr(int32_t aNamespaceID, nsAtom* aName,
|
|||||||
AfterMaybeChangeAttr(aNamespaceID, aName, aNotify);
|
AfterMaybeChangeAttr(aNamespaceID, aName, aNotify);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (aName == nsGkAtoms::src) {
|
||||||
|
RefreshFeaturePolicy();
|
||||||
|
}
|
||||||
|
|
||||||
if (aNamespaceID == kNameSpaceID_None &&
|
if (aNamespaceID == kNameSpaceID_None &&
|
||||||
aName == nsGkAtoms::allowfullscreen && mFrameLoader) {
|
aName == nsGkAtoms::allowfullscreen && mFrameLoader) {
|
||||||
if (auto* bc = mFrameLoader->GetExtantBrowsingContext()) {
|
if (auto* bc = mFrameLoader->GetExtantBrowsingContext()) {
|
||||||
|
|||||||
@@ -100,6 +100,11 @@ void HTMLObjectElement::AfterSetAttr(int32_t aNamespaceID, nsAtom* aName,
|
|||||||
nsIPrincipal* aSubjectPrincipal,
|
nsIPrincipal* aSubjectPrincipal,
|
||||||
bool aNotify) {
|
bool aNotify) {
|
||||||
AfterMaybeChangeAttr(aNamespaceID, aName, aNotify);
|
AfterMaybeChangeAttr(aNamespaceID, aName, aNotify);
|
||||||
|
|
||||||
|
if (aName == nsGkAtoms::data) {
|
||||||
|
RefreshFeaturePolicy();
|
||||||
|
}
|
||||||
|
|
||||||
return nsGenericHTMLFormControlElement::AfterSetAttr(
|
return nsGenericHTMLFormControlElement::AfterSetAttr(
|
||||||
aNamespaceID, aName, aValue, aOldValue, aSubjectPrincipal, aNotify);
|
aNamespaceID, aName, aValue, aOldValue, aSubjectPrincipal, aNotify);
|
||||||
}
|
}
|
||||||
@@ -126,6 +131,7 @@ void HTMLObjectElement::AfterMaybeChangeAttr(int32_t aNamespaceID,
|
|||||||
BlockEmbedOrObjectContentLoading()) {
|
BlockEmbedOrObjectContentLoading()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsContentUtils::AddScriptRunner(NS_NewRunnableFunction(
|
nsContentUtils::AddScriptRunner(NS_NewRunnableFunction(
|
||||||
"HTMLObjectElement::LoadObject",
|
"HTMLObjectElement::LoadObject",
|
||||||
[self = RefPtr<HTMLObjectElement>(this), aNotify]() {
|
[self = RefPtr<HTMLObjectElement>(this), aNotify]() {
|
||||||
|
|||||||
@@ -2048,6 +2048,15 @@ bool DocumentLoadListener::MaybeTriggerProcessSwitch(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// At this point the element has stored the container feature policy in
|
||||||
|
// the new browsing context, but we need to make sure that we copy it
|
||||||
|
// over to the load info.
|
||||||
|
nsCOMPtr<nsILoadInfo> loadInfo = self->mChannel->LoadInfo();
|
||||||
|
if (aBrowsingContext->GetContainerFeaturePolicy()) {
|
||||||
|
loadInfo->SetContainerFeaturePolicyInfo(
|
||||||
|
*aBrowsingContext->GetContainerFeaturePolicy());
|
||||||
|
}
|
||||||
|
|
||||||
MOZ_LOG(gProcessIsolationLog, LogLevel::Verbose,
|
MOZ_LOG(gProcessIsolationLog, LogLevel::Verbose,
|
||||||
("Process Switch: Upgraded Object to Document Load"));
|
("Process Switch: Upgraded Object to Document Load"));
|
||||||
self->TriggerProcessSwitch(aBrowsingContext, options);
|
self->TriggerProcessSwitch(aBrowsingContext, options);
|
||||||
|
|||||||
Reference in New Issue
Block a user