зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1406278: Part 2c - Use subject principal as triggering principal in <img> "srcset" attribute. r=bz
MozReview-Commit-ID: 784EsgwBcS1 --HG-- extra : rebase_source : 01b701f84c425786b66cd9787d4e570dd9341ae5
This commit is contained in:
Родитель
d72aa193c4
Коммит
d038453393
|
@ -116,7 +116,8 @@ ResponsiveImageSelector::~ResponsiveImageSelector()
|
|||
|
||||
// http://www.whatwg.org/specs/web-apps/current-work/#processing-the-image-candidates
|
||||
bool
|
||||
ResponsiveImageSelector::SetCandidatesFromSourceSet(const nsAString & aSrcSet)
|
||||
ResponsiveImageSelector::SetCandidatesFromSourceSet(const nsAString & aSrcSet,
|
||||
nsIPrincipal* aTriggeringPrincipal)
|
||||
{
|
||||
ClearSelectedCandidate();
|
||||
|
||||
|
@ -168,6 +169,8 @@ ResponsiveImageSelector::SetCandidatesFromSourceSet(const nsAString & aSrcSet)
|
|||
ResponsiveImageCandidate candidate;
|
||||
if (candidate.ConsumeDescriptors(iter, end)) {
|
||||
candidate.SetURLSpec(urlStr);
|
||||
candidate.SetTriggeringPrincipal(nsContentUtils::GetAttrTriggeringPrincipal(
|
||||
Content(), urlStr, aTriggeringPrincipal));
|
||||
AppendCandidateIfUnique(candidate);
|
||||
}
|
||||
}
|
||||
|
@ -208,7 +211,8 @@ ResponsiveImageSelector::Document()
|
|||
}
|
||||
|
||||
void
|
||||
ResponsiveImageSelector::SetDefaultSource(const nsAString& aURLString)
|
||||
ResponsiveImageSelector::SetDefaultSource(const nsAString& aURLString,
|
||||
nsIPrincipal* aPrincipal)
|
||||
{
|
||||
ClearSelectedCandidate();
|
||||
|
||||
|
@ -220,6 +224,7 @@ ResponsiveImageSelector::SetDefaultSource(const nsAString& aURLString)
|
|||
}
|
||||
|
||||
mDefaultSourceURL = aURLString;
|
||||
mDefaultSourceTriggeringPrincipal = aPrincipal;
|
||||
|
||||
// Add new default to end of list
|
||||
MaybeAppendDefaultCandidate();
|
||||
|
@ -292,6 +297,7 @@ ResponsiveImageSelector::MaybeAppendDefaultCandidate()
|
|||
ResponsiveImageCandidate defaultCandidate;
|
||||
defaultCandidate.SetParameterDefault();
|
||||
defaultCandidate.SetURLSpec(mDefaultSourceURL);
|
||||
defaultCandidate.SetTriggeringPrincipal(mDefaultSourceTriggeringPrincipal);
|
||||
// We don't use MaybeAppend since we want to keep this even if it can never
|
||||
// match, as it may if the source set changes.
|
||||
mCandidates.AppendElement(defaultCandidate);
|
||||
|
@ -330,6 +336,17 @@ ResponsiveImageSelector::GetSelectedImageDensity()
|
|||
return mCandidates[bestIndex].Density(this);
|
||||
}
|
||||
|
||||
nsIPrincipal*
|
||||
ResponsiveImageSelector::GetSelectedImageTriggeringPrincipal()
|
||||
{
|
||||
int bestIndex = GetSelectedCandidateIndex();
|
||||
if (bestIndex < 0) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return mCandidates[bestIndex].TriggeringPrincipal();
|
||||
}
|
||||
|
||||
bool
|
||||
ResponsiveImageSelector::SelectImage(bool aReselect)
|
||||
{
|
||||
|
@ -458,8 +475,10 @@ ResponsiveImageCandidate::ResponsiveImageCandidate()
|
|||
}
|
||||
|
||||
ResponsiveImageCandidate::ResponsiveImageCandidate(const nsAString& aURLString,
|
||||
double aDensity)
|
||||
double aDensity,
|
||||
nsIPrincipal* aTriggeringPrincipal)
|
||||
: mURLString(aURLString)
|
||||
, mTriggeringPrincipal(aTriggeringPrincipal)
|
||||
{
|
||||
mType = eCandidateType_Density;
|
||||
mValue.mDensity = aDensity;
|
||||
|
@ -472,6 +491,12 @@ ResponsiveImageCandidate::SetURLSpec(const nsAString& aURLString)
|
|||
mURLString = aURLString;
|
||||
}
|
||||
|
||||
void
|
||||
ResponsiveImageCandidate::SetTriggeringPrincipal(nsIPrincipal* aPrincipal)
|
||||
{
|
||||
mTriggeringPrincipal = aPrincipal;
|
||||
}
|
||||
|
||||
void
|
||||
ResponsiveImageCandidate::SetParameterAsComputedWidth(int32_t aWidth)
|
||||
{
|
||||
|
@ -718,6 +743,12 @@ ResponsiveImageCandidate::URLString() const
|
|||
return mURLString;
|
||||
}
|
||||
|
||||
nsIPrincipal*
|
||||
ResponsiveImageCandidate::TriggeringPrincipal() const
|
||||
{
|
||||
return mTriggeringPrincipal;
|
||||
}
|
||||
|
||||
double
|
||||
ResponsiveImageCandidate::Density(ResponsiveImageSelector *aSelector) const
|
||||
{
|
||||
|
|
|
@ -45,14 +45,16 @@ public:
|
|||
|
||||
// Given a srcset string, parse and replace current candidates (does not
|
||||
// replace default source)
|
||||
bool SetCandidatesFromSourceSet(const nsAString & aSrcSet);
|
||||
bool SetCandidatesFromSourceSet(const nsAString & aSrcSet,
|
||||
nsIPrincipal* aTriggeringPrincipal = nullptr);
|
||||
|
||||
// Fill the source sizes from a valid sizes descriptor. Returns false if
|
||||
// descriptor is invalid.
|
||||
bool SetSizesFromDescriptor(const nsAString & aSizesDescriptor);
|
||||
|
||||
// Set the default source, treated as the least-precedence 1.0 density source.
|
||||
void SetDefaultSource(const nsAString& aURLString);
|
||||
void SetDefaultSource(const nsAString& aURLString,
|
||||
nsIPrincipal* aPrincipal = nullptr);
|
||||
|
||||
uint32_t NumCandidates(bool aIncludeDefault = true);
|
||||
|
||||
|
@ -70,6 +72,7 @@ public:
|
|||
// Returns false if there is no selected image
|
||||
bool GetSelectedImageURLSpec(nsAString& aResult);
|
||||
double GetSelectedImageDensity();
|
||||
nsIPrincipal* GetSelectedImageTriggeringPrincipal();
|
||||
|
||||
// Runs image selection now if necessary. If an image has already
|
||||
// been choosen, takes no action unless aReselect is true.
|
||||
|
@ -108,6 +111,7 @@ private:
|
|||
nsCOMPtr<nsINode> mOwnerNode;
|
||||
// The cached URL for default candidate.
|
||||
nsString mDefaultSourceURL;
|
||||
nsCOMPtr<nsIPrincipal> mDefaultSourceTriggeringPrincipal;
|
||||
// If this array contains an eCandidateType_Default, it should be the last
|
||||
// element, such that the Setters can preserve/replace it respectively.
|
||||
nsTArray<ResponsiveImageCandidate> mCandidates;
|
||||
|
@ -123,9 +127,11 @@ private:
|
|||
class ResponsiveImageCandidate {
|
||||
public:
|
||||
ResponsiveImageCandidate();
|
||||
ResponsiveImageCandidate(const nsAString& aURLString, double aDensity);
|
||||
ResponsiveImageCandidate(const nsAString& aURLString, double aDensity,
|
||||
nsIPrincipal* aTriggeringPrincipal = nullptr);
|
||||
|
||||
void SetURLSpec(const nsAString& aURLString);
|
||||
void SetTriggeringPrincipal(nsIPrincipal* aPrincipal);
|
||||
// Set this as a default-candidate. This behaves the same as density 1.0, but
|
||||
// has a differing type such that it can be replaced by subsequent
|
||||
// SetDefaultSource calls.
|
||||
|
@ -148,6 +154,7 @@ public:
|
|||
bool HasSameParameter(const ResponsiveImageCandidate & aOther) const;
|
||||
|
||||
const nsAString& URLString() const;
|
||||
nsIPrincipal* TriggeringPrincipal() const;
|
||||
|
||||
// Compute and return the density relative to a selector.
|
||||
double Density(ResponsiveImageSelector *aSelector) const;
|
||||
|
@ -172,6 +179,7 @@ public:
|
|||
private:
|
||||
|
||||
nsString mURLString;
|
||||
nsCOMPtr<nsIPrincipal> mTriggeringPrincipal;
|
||||
eCandidateType mType;
|
||||
union {
|
||||
double mDensity;
|
||||
|
|
|
@ -368,6 +368,8 @@ HTMLImageElement::AfterSetAttr(int32_t aNameSpaceID, nsAtom* aName,
|
|||
// initaiated by a user interaction.
|
||||
mUseUrgentStartForChannel = EventStateManager::IsHandlingUserInput();
|
||||
|
||||
mSrcsetTriggeringPrincipal = aMaybeScriptedPrincipal;
|
||||
|
||||
PictureSourceSrcsetChanged(this, attrVal.String(), aNotify);
|
||||
} else if (aName == nsGkAtoms::sizes &&
|
||||
aNameSpaceID == kNameSpaceID_None) {
|
||||
|
@ -426,7 +428,8 @@ HTMLImageElement::AfterMaybeChangeAttr(int32_t aNamespaceID, nsAtom* aName,
|
|||
if (InResponsiveMode()) {
|
||||
if (mResponsiveSelector &&
|
||||
mResponsiveSelector->Content() == this) {
|
||||
mResponsiveSelector->SetDefaultSource(aValue.String());
|
||||
mResponsiveSelector->SetDefaultSource(aValue.String(),
|
||||
mSrcTriggeringPrincipal);
|
||||
}
|
||||
QueueImageLoadTask(true);
|
||||
} else if (aNotify && OwnerDoc()->IsCurrentActiveDocument()) {
|
||||
|
@ -981,13 +984,15 @@ HTMLImageElement::LoadSelectedImage(bool aForce, bool aNotify, bool aAlwaysLoad)
|
|||
double currentDensity = 1.0; // default to 1.0 for the src attribute case
|
||||
if (mResponsiveSelector) {
|
||||
nsCOMPtr<nsIURI> url = mResponsiveSelector->GetSelectedImageURL();
|
||||
nsCOMPtr<nsIPrincipal> triggeringPrincipal = mResponsiveSelector->GetSelectedImageTriggeringPrincipal();
|
||||
selectedSource = url;
|
||||
currentDensity = mResponsiveSelector->GetSelectedImageDensity();
|
||||
if (!aAlwaysLoad && SelectedSourceMatchesLast(selectedSource, currentDensity)) {
|
||||
return NS_OK;
|
||||
}
|
||||
if (url) {
|
||||
rv = LoadImage(url, aForce, aNotify, eImageLoadType_Imageset);
|
||||
rv = LoadImage(url, aForce, aNotify, eImageLoadType_Imageset,
|
||||
triggeringPrincipal);
|
||||
}
|
||||
} else {
|
||||
nsAutoString src;
|
||||
|
@ -1036,7 +1041,11 @@ HTMLImageElement::PictureSourceSrcsetChanged(nsIContent *aSourceNode,
|
|||
if (aSourceNode == currentSrc) {
|
||||
// We're currently using this node as our responsive selector
|
||||
// source.
|
||||
mResponsiveSelector->SetCandidatesFromSourceSet(aNewValue);
|
||||
nsCOMPtr<nsIPrincipal> principal;
|
||||
if (aSourceNode == this) {
|
||||
principal = mSrcsetTriggeringPrincipal;
|
||||
}
|
||||
mResponsiveSelector->SetCandidatesFromSourceSet(aNewValue, principal);
|
||||
}
|
||||
|
||||
if (!mInDocResponsiveContent && IsInComposedDoc()) {
|
||||
|
@ -1221,6 +1230,8 @@ HTMLImageElement::SourceElementMatches(nsIContent* aSourceNode)
|
|||
bool
|
||||
HTMLImageElement::TryCreateResponsiveSelector(nsIContent *aSourceNode)
|
||||
{
|
||||
nsCOMPtr<nsIPrincipal> principal;
|
||||
|
||||
// Skip if this is not a <source> with matching media query
|
||||
bool isSourceTag = aSourceNode->IsHTMLElement(nsGkAtoms::source);
|
||||
if (isSourceTag) {
|
||||
|
@ -1230,6 +1241,7 @@ HTMLImageElement::TryCreateResponsiveSelector(nsIContent *aSourceNode)
|
|||
} 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
|
||||
|
@ -1245,7 +1257,7 @@ HTMLImageElement::TryCreateResponsiveSelector(nsIContent *aSourceNode)
|
|||
|
||||
// Try to parse
|
||||
RefPtr<ResponsiveImageSelector> sel = new ResponsiveImageSelector(aSourceNode);
|
||||
if (!sel->SetCandidatesFromSourceSet(srcset)) {
|
||||
if (!sel->SetCandidatesFromSourceSet(srcset, principal)) {
|
||||
// No possible candidates, don't need to bother parsing sizes
|
||||
return false;
|
||||
}
|
||||
|
@ -1259,7 +1271,7 @@ HTMLImageElement::TryCreateResponsiveSelector(nsIContent *aSourceNode)
|
|||
MOZ_ASSERT(aSourceNode == this);
|
||||
nsAutoString src;
|
||||
if (GetAttr(kNameSpaceID_None, nsGkAtoms::src, src) && !src.IsEmpty()) {
|
||||
sel->SetDefaultSource(src);
|
||||
sel->SetDefaultSource(src, mSrcTriggeringPrincipal);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -150,13 +150,13 @@ public:
|
|||
{
|
||||
SetHTMLAttr(nsGkAtoms::src, aSrc, aTriggeringPrincipal, aError);
|
||||
}
|
||||
void GetSrcset(nsAString& aSrcset)
|
||||
void GetSrcset(nsAString& aSrcset, nsIPrincipal&)
|
||||
{
|
||||
GetHTMLAttr(nsGkAtoms::srcset, aSrcset);
|
||||
}
|
||||
void SetSrcset(const nsAString& aSrcset, ErrorResult& aError)
|
||||
void SetSrcset(const nsAString& aSrcset, nsIPrincipal& aTriggeringPrincipal, ErrorResult& aError)
|
||||
{
|
||||
SetHTMLAttr(nsGkAtoms::srcset, aSrcset, aError);
|
||||
SetHTMLAttr(nsGkAtoms::srcset, aSrcset, aTriggeringPrincipal, aError);
|
||||
}
|
||||
void GetCrossOrigin(nsAString& aResult)
|
||||
{
|
||||
|
@ -427,6 +427,7 @@ private:
|
|||
bool mInDocResponsiveContent;
|
||||
RefPtr<ImageLoadTask> mPendingImageLoadTask;
|
||||
nsCOMPtr<nsIPrincipal> mSrcTriggeringPrincipal;
|
||||
nsCOMPtr<nsIPrincipal> mSrcsetTriggeringPrincipal;
|
||||
|
||||
// Last URL that was attempted to load by this element.
|
||||
nsCOMPtr<nsIURI> mLastSelectedSource;
|
||||
|
|
|
@ -23,7 +23,7 @@ interface HTMLImageElement : HTMLElement {
|
|||
attribute DOMString alt;
|
||||
[CEReactions, NeedsSubjectPrincipal, SetterThrows]
|
||||
attribute DOMString src;
|
||||
[CEReactions, SetterThrows]
|
||||
[CEReactions, NeedsSubjectPrincipal, SetterThrows]
|
||||
attribute DOMString srcset;
|
||||
[CEReactions, SetterThrows]
|
||||
attribute DOMString? crossOrigin;
|
||||
|
|
|
@ -437,6 +437,11 @@ add_task(async function test_contentscript_triggeringPrincipals() {
|
|||
element: ["img", {}],
|
||||
src: "img.png",
|
||||
},
|
||||
{
|
||||
element: ["img", {}],
|
||||
src: "imgset.png",
|
||||
srcAttr: "srcset",
|
||||
},
|
||||
];
|
||||
|
||||
/**
|
||||
|
|
Загрузка…
Ссылка в новой задаче