Bug 1406278: Part 6 - Use subject principal as triggering principal in <source> "srcset" attribute for <picture>. r?bz
MozReview-Commit-ID: DFq3k9PSOgA
--- a/dom/html/HTMLImageElement.cpp
+++ b/dom/html/HTMLImageElement.cpp
@@ -1037,16 +1037,19 @@ HTMLImageElement::PictureSourceSrcsetCha
mResponsiveSelector ? mResponsiveSelector->Content() : nullptr;
if (aSourceNode == currentSrc) {
// We're currently using this node as our responsive selector
// source.
nsCOMPtr<nsIPrincipal> principal;
if (aSourceNode == this) {
principal = mSrcsetTriggeringPrincipal;
+ } else if (aSourceNode->IsHTMLElement(nsGkAtoms::source)) {
+ auto* source = HTMLSourceElement::FromContent(aSourceNode);
+ principal = source->GetSrcsetTriggeringPrincipal();
}
mResponsiveSelector->SetCandidatesFromSourceSet(aNewValue, principal);
}
if (!mInDocResponsiveContent && IsInComposedDoc()) {
nsIDocument* doc = GetOurOwnerDoc();
if (doc) {
doc->AddResponsiveContent(this);
@@ -1231,16 +1234,18 @@ HTMLImageElement::TryCreateResponsiveSel
nsCOMPtr<nsIPrincipal> principal;
// Skip if this is not a <source> with matching media query
bool isSourceTag = aSourceNode->IsHTMLElement(nsGkAtoms::source);
if (isSourceTag) {
if (!SourceElementMatches(aSourceNode)) {
return false;
}
+ auto* source = HTMLSourceElement::FromContent(aSourceNode);
+ principal = source->GetSrcsetTriggeringPrincipal();
} else if (aSourceNode->IsHTMLElement(nsGkAtoms::img)) {
// Otherwise this is the <img> tag itself
MOZ_ASSERT(aSourceNode == this);
principal = mSrcsetTriggeringPrincipal;
}
// Skip if has no srcset or an empty srcset
nsString srcset;
--- a/dom/html/HTMLSourceElement.cpp
+++ b/dom/html/HTMLSourceElement.cpp
@@ -95,16 +95,21 @@ HTMLSourceElement::UpdateMediaList(const
nsresult
HTMLSourceElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
const nsAttrValue* aValue,
const nsAttrValue* aOldValue,
nsIPrincipal* aSubjectPrincipal,
bool aNotify)
{
+ if (aNameSpaceID == kNameSpaceID_None && aName == nsGkAtoms::srcset) {
+ mSrcsetTriggeringPrincipal = nsContentUtils::GetAttrTriggeringPrincipal(
+ this, aValue ? aValue->GetStringValue() : EmptyString(),
+ aSubjectPrincipal);
+ }
// If we are associated with a <picture> with a valid <img>, notify it of
// responsive parameter changes
Element *parent = nsINode::GetParentElement();
if (aNameSpaceID == kNameSpaceID_None &&
(aName == nsGkAtoms::srcset ||
aName == nsGkAtoms::sizes ||
aName == nsGkAtoms::media ||
aName == nsGkAtoms::type) &&
--- a/dom/html/HTMLSourceElement.h
+++ b/dom/html/HTMLSourceElement.h
@@ -68,32 +68,37 @@ public:
SetHTMLAttr(nsGkAtoms::src, aSrc, aPrincipal, rv);
}
nsIPrincipal* GetSrcTriggeringPrincipal() const
{
return mSrcTriggeringPrincipal;
}
+ nsIPrincipal* GetSrcsetTriggeringPrincipal() const
+ {
+ return mSrcsetTriggeringPrincipal;
+ }
+
void GetType(DOMString& aType)
{
GetHTMLAttr(nsGkAtoms::type, aType);
}
void SetType(const nsAString& aType, ErrorResult& rv)
{
SetHTMLAttr(nsGkAtoms::type, aType, rv);
}
- void GetSrcset(DOMString& aSrcset)
+ void GetSrcset(DOMString& aSrcset, nsIPrincipal&)
{
GetHTMLAttr(nsGkAtoms::srcset, aSrcset);
}
- void SetSrcset(const nsAString& aSrcset, mozilla::ErrorResult& rv)
+ void SetSrcset(const nsAString& aSrcset, nsIPrincipal& aPrincipal, mozilla::ErrorResult& rv)
{
- SetHTMLAttr(nsGkAtoms::srcset, aSrcset, rv);
+ SetHTMLAttr(nsGkAtoms::srcset, aSrcset, aPrincipal, rv);
}
void GetSizes(DOMString& aSizes)
{
GetHTMLAttr(nsGkAtoms::sizes, aSizes);
}
void SetSizes(const nsAString& aSizes, mozilla::ErrorResult& rv)
{
@@ -123,16 +128,19 @@ protected:
private:
RefPtr<MediaList> mMediaList;
RefPtr<MediaSource> mSrcMediaSource;
// The triggering principal for the src attribute.
nsCOMPtr<nsIPrincipal> mSrcTriggeringPrincipal;
+ // The triggering principal for the srcset attribute.
+ nsCOMPtr<nsIPrincipal> mSrcsetTriggeringPrincipal;
+
// Generates a new MediaList using the given input
void UpdateMediaList(const nsAttrValue* aValue);
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_HTMLSourceElement_h
--- a/dom/webidl/HTMLSourceElement.webidl
+++ b/dom/webidl/HTMLSourceElement.webidl
@@ -15,15 +15,15 @@
interface HTMLSourceElement : HTMLElement {
[CEReactions, NeedsSubjectPrincipal, SetterThrows]
attribute DOMString src;
[CEReactions, SetterThrows]
attribute DOMString type;
};
partial interface HTMLSourceElement {
- [CEReactions, SetterThrows]
+ [CEReactions, NeedsSubjectPrincipal, SetterThrows]
attribute DOMString srcset;
[CEReactions, SetterThrows]
attribute DOMString sizes;
[CEReactions, SetterThrows]
attribute DOMString media;
};
--- a/toolkit/components/extensions/test/xpcshell/test_ext_contentscript_triggeringPrincipal.js
+++ b/toolkit/components/extensions/test/xpcshell/test_ext_contentscript_triggeringPrincipal.js
@@ -444,16 +444,21 @@ add_task(async function test_contentscri
src: "img.png",
},
{
element: ["img", {}],
src: "imgset.png",
srcAttr: "srcset",
},
{
+ element: ["picture", {}, ["source", {}], ["img", {}]],
+ src: "picture.png",
+ srcAttr: "srcset",
+ },
+ {
element: ["script", {}],
src: "script.js",
liveSrc: false,
},
{
element: ["video", {}],
src: "video.webm",
},