mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-23 04:41:11 +00:00
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:
parent
3f3edff318
commit
01fc6bda19
@ -218,8 +218,6 @@ already_AddRefed<nsIDocShell> nsObjectLoadingContent::SetupDocShell(
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
MaybeStoreCrossOriginFeaturePolicy();
|
||||
|
||||
return docShell.forget();
|
||||
}
|
||||
|
||||
@ -1554,6 +1552,7 @@ void nsObjectLoadingContent::Destroy() {
|
||||
void nsObjectLoadingContent::Traverse(nsObjectLoadingContent* tmp,
|
||||
nsCycleCollectionTraversalCallback& cb) {
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mFrameLoader);
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mFeaturePolicy);
|
||||
}
|
||||
|
||||
/* static */
|
||||
@ -1562,6 +1561,7 @@ void nsObjectLoadingContent::Unlink(nsObjectLoadingContent* tmp) {
|
||||
tmp->mFrameLoader->Destroy();
|
||||
}
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mFrameLoader);
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mFeaturePolicy);
|
||||
}
|
||||
|
||||
void nsObjectLoadingContent::UnloadObject(bool aResetState) {
|
||||
@ -1720,6 +1720,13 @@ nsObjectLoadingContent::UpgradeLoadToDocument(
|
||||
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);
|
||||
return NS_OK;
|
||||
}
|
||||
@ -1818,6 +1825,9 @@ void nsObjectLoadingContent::SubdocumentImageLoadComplete(nsresult aResult) {
|
||||
|
||||
void nsObjectLoadingContent::MaybeStoreCrossOriginFeaturePolicy() {
|
||||
MOZ_DIAGNOSTIC_ASSERT(mFrameLoader);
|
||||
if (!mFrameLoader) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If the browsingContext is not ready (because docshell is dead), don't try
|
||||
// to create one.
|
||||
@ -1831,15 +1841,54 @@ void nsObjectLoadingContent::MaybeStoreCrossOriginFeaturePolicy() {
|
||||
return;
|
||||
}
|
||||
|
||||
Element* el = AsElement();
|
||||
auto* el = nsGenericHTMLElement::FromNode(AsElement());
|
||||
if (!el->IsInComposedDoc()) {
|
||||
return;
|
||||
}
|
||||
|
||||
FeaturePolicy* featurePolicy = el->OwnerDoc()->FeaturePolicy();
|
||||
|
||||
if (ContentChild* cc = ContentChild::GetSingleton(); cc && featurePolicy) {
|
||||
if (ContentChild* cc = ContentChild::GetSingleton()) {
|
||||
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 {
|
||||
struct BindContext;
|
||||
class FeaturePolicy;
|
||||
template <typename T>
|
||||
class Sequence;
|
||||
class HTMLIFrameElement;
|
||||
@ -213,6 +214,14 @@ class nsObjectLoadingContent : public nsIStreamListener,
|
||||
*/
|
||||
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:
|
||||
// Object parameter changes returned by UpdateObjectParameters
|
||||
enum ParameterUpdateFlags {
|
||||
@ -393,6 +402,14 @@ class nsObjectLoadingContent : public nsIStreamListener,
|
||||
*/
|
||||
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.)
|
||||
nsCOMPtr<nsIStreamListener> mFinalListener;
|
||||
|
||||
@ -464,6 +481,14 @@ class nsObjectLoadingContent : public nsIStreamListener,
|
||||
// our own frame.
|
||||
mozilla::Maybe<mozilla::IntrinsicSize> mSubdocumentIntrinsicSize;
|
||||
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
|
||||
|
@ -79,6 +79,10 @@ void HTMLEmbedElement::AfterSetAttr(int32_t aNamespaceID, nsAtom* aName,
|
||||
AfterMaybeChangeAttr(aNamespaceID, aName, aNotify);
|
||||
}
|
||||
|
||||
if (aName == nsGkAtoms::src) {
|
||||
RefreshFeaturePolicy();
|
||||
}
|
||||
|
||||
if (aNamespaceID == kNameSpaceID_None &&
|
||||
aName == nsGkAtoms::allowfullscreen && mFrameLoader) {
|
||||
if (auto* bc = mFrameLoader->GetExtantBrowsingContext()) {
|
||||
|
@ -100,6 +100,11 @@ void HTMLObjectElement::AfterSetAttr(int32_t aNamespaceID, nsAtom* aName,
|
||||
nsIPrincipal* aSubjectPrincipal,
|
||||
bool aNotify) {
|
||||
AfterMaybeChangeAttr(aNamespaceID, aName, aNotify);
|
||||
|
||||
if (aName == nsGkAtoms::data) {
|
||||
RefreshFeaturePolicy();
|
||||
}
|
||||
|
||||
return nsGenericHTMLFormControlElement::AfterSetAttr(
|
||||
aNamespaceID, aName, aValue, aOldValue, aSubjectPrincipal, aNotify);
|
||||
}
|
||||
@ -126,6 +131,7 @@ void HTMLObjectElement::AfterMaybeChangeAttr(int32_t aNamespaceID,
|
||||
BlockEmbedOrObjectContentLoading()) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsContentUtils::AddScriptRunner(NS_NewRunnableFunction(
|
||||
"HTMLObjectElement::LoadObject",
|
||||
[self = RefPtr<HTMLObjectElement>(this), aNotify]() {
|
||||
|
@ -2048,6 +2048,15 @@ bool DocumentLoadListener::MaybeTriggerProcessSwitch(
|
||||
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,
|
||||
("Process Switch: Upgraded Object to Document Load"));
|
||||
self->TriggerProcessSwitch(aBrowsingContext, options);
|
||||
|
Loading…
Reference in New Issue
Block a user