Bug 1415352: Part 1b - Store the subject principal when parsing style attributes. r?bz
This change stores the subject principal in the URLExtraData when parsing
style attributes, which causes it to be used as the triggering principal for
those loads rather than defaulting to the document principal.
MozReview-Commit-ID: 22tmNRRCgaj
--- a/dom/base/nsAttrValue.cpp
+++ b/dom/base/nsAttrValue.cpp
@@ -1720,53 +1720,62 @@ nsAttrValue::LoadImage(nsIDocument* aDoc
NS_ADDREF(image);
cont->mValue.mImage = image;
NS_RELEASE(url);
cont->mType = eImage;
}
bool
nsAttrValue::ParseStyleAttribute(const nsAString& aString,
+ nsIPrincipal* aMaybeScriptedPrincipal,
nsStyledElement* aElement)
{
nsIDocument* ownerDoc = aElement->OwnerDoc();
nsHTMLCSSStyleSheet* sheet = ownerDoc->GetInlineStyleSheet();
nsCOMPtr<nsIURI> baseURI = aElement->GetBaseURIForStyleAttr();
nsIURI* docURI = ownerDoc->GetDocumentURI();
NS_ASSERTION(aElement->NodePrincipal() == ownerDoc->NodePrincipal(),
"This is unexpected");
+ nsCOMPtr<nsIPrincipal> principal = (
+ aMaybeScriptedPrincipal ? aMaybeScriptedPrincipal
+ : aElement->NodePrincipal());
+
// If the (immutable) document URI does not match the element's base URI
// (the common case is that they do match) do not cache the rule. This is
// because the results of the CSS parser are dependent on these URIs, and we
// do not want to have to account for the URIs in the hash lookup.
- bool cachingAllowed = sheet && baseURI == docURI;
+ // Similarly, if the triggering principal does not match the node principal,
+ // do not cache the rule, since the principal will be encoded in any parsed
+ // URLs in the rule.
+ bool cachingAllowed = (sheet && baseURI == docURI &&
+ principal == aElement->NodePrincipal());
if (cachingAllowed) {
MiscContainer* cont = sheet->LookupStyleAttr(aString);
if (cont) {
// Set our MiscContainer to the cached one.
NS_ADDREF(cont);
SetPtrValueAndType(cont, eOtherBase);
return true;
}
}
RefPtr<DeclarationBlock> decl;
if (ownerDoc->GetStyleBackendType() == StyleBackendType::Servo) {
RefPtr<URLExtraData> data = new URLExtraData(baseURI, docURI,
- aElement->NodePrincipal());
+ principal);
decl = ServoDeclarationBlock::FromCssText(aString, data,
ownerDoc->GetCompatibilityMode(),
ownerDoc->CSSLoader());
} else {
css::Loader* cssLoader = ownerDoc->CSSLoader();
nsCSSParser cssParser(cssLoader);
decl = cssParser.ParseStyleAttribute(aString, docURI, baseURI,
- aElement->NodePrincipal());
+ principal);
}
if (!decl) {
return false;
}
decl->SetHTMLCSSStyleSheet(sheet);
SetTo(decl.forget(), &aString);
if (cachingAllowed) {
--- a/dom/base/nsAttrValue.h
+++ b/dom/base/nsAttrValue.h
@@ -430,16 +430,17 @@ public:
/**
* Parse a string into a CSS style rule.
*
* @param aString the style attribute value to be parsed.
* @param aElement the element the attribute is set on.
*/
bool ParseStyleAttribute(const nsAString& aString,
+ nsIPrincipal* aMaybeScriptedPrincipal,
nsStyledElement* aElement);
size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
private:
// These have to be the same as in ValueType
enum ValueBaseType {
eStringBase = eString, // 00
--- a/dom/base/nsStyledElement.cpp
+++ b/dom/base/nsStyledElement.cpp
@@ -38,17 +38,17 @@ NS_IMPL_QUERY_INTERFACE_CYCLE_COLLECTION
bool
nsStyledElement::ParseAttribute(int32_t aNamespaceID,
nsAtom* aAttribute,
const nsAString& aValue,
nsIPrincipal* aMaybeScriptedPrincipal,
nsAttrValue& aResult)
{
if (aAttribute == nsGkAtoms::style && aNamespaceID == kNameSpaceID_None) {
- ParseStyleAttribute(aValue, aResult, false);
+ ParseStyleAttribute(aValue, aMaybeScriptedPrincipal, aResult, false);
return true;
}
return nsStyledElementBase::ParseAttribute(aNamespaceID, aAttribute, aValue,
aMaybeScriptedPrincipal, aResult);
}
nsresult
@@ -141,17 +141,17 @@ nsStyledElement::ReparseStyleAttribute(b
if (!MayHaveStyle()) {
return NS_OK;
}
const nsAttrValue* oldVal = mAttrsAndChildren.GetAttr(nsGkAtoms::style);
if (oldVal && (aForceIfAlreadyParsed || oldVal->Type() != nsAttrValue::eCSSDeclaration)) {
nsAttrValue attrValue;
nsAutoString stringValue;
oldVal->ToString(stringValue);
- ParseStyleAttribute(stringValue, attrValue, aForceInDataDoc);
+ ParseStyleAttribute(stringValue, nullptr, attrValue, aForceInDataDoc);
// Don't bother going through SetInlineStyleDeclaration; we don't
// want to fire off mutation events or document notifications anyway
bool oldValueSet;
nsresult rv = mAttrsAndChildren.SetAndSwapAttr(nsGkAtoms::style, attrValue,
&oldValueSet);
NS_ENSURE_SUCCESS(rv, rv);
}
@@ -175,16 +175,17 @@ nsStyledElement::GetExistingStyle()
return nullptr;
}
return slots->mStyle;
}
void
nsStyledElement::ParseStyleAttribute(const nsAString& aValue,
+ nsIPrincipal* aMaybeScriptedPrincipal,
nsAttrValue& aResult,
bool aForceInDataDoc)
{
nsIDocument* doc = OwnerDoc();
bool isNativeAnon = IsInNativeAnonymousSubtree();
if (!isNativeAnon &&
!nsStyleUtil::CSPAllowsInlineStyle(nullptr, NodePrincipal(),
@@ -202,15 +203,16 @@ nsStyledElement::ParseStyleAttribute(con
nsAutoString styleType;
doc->GetHeaderData(nsGkAtoms::headerContentStyleType, styleType);
if (!styleType.IsEmpty()) {
static const char textCssStr[] = "text/css";
isCSS = (styleType.EqualsIgnoreCase(textCssStr, sizeof(textCssStr) - 1));
}
}
- if (isCSS && aResult.ParseStyleAttribute(aValue, this)) {
+ if (isCSS && aResult.ParseStyleAttribute(aValue, aMaybeScriptedPrincipal,
+ this)) {
return;
}
}
aResult.SetTo(aValue);
}
--- a/dom/base/nsStyledElement.h
+++ b/dom/base/nsStyledElement.h
@@ -59,16 +59,17 @@ protected:
/**
* Parse a style attr value into a CSS rulestruct (or, if there is no
* document, leave it as a string) and return as nsAttrValue.
*
* @param aValue the value to parse
* @param aResult the resulting HTMLValue [OUT]
*/
void ParseStyleAttribute(const nsAString& aValue,
+ nsIPrincipal* aMaybeScriptedPrincipal,
nsAttrValue& aResult,
bool aForceInDataDoc);
virtual bool ParseAttribute(int32_t aNamespaceID, nsAtom* aAttribute,
const nsAString& aValue,
nsIPrincipal* aMaybeScriptedPrincipal,
nsAttrValue& aResult) override;
--- a/dom/svg/nsSVGElement.cpp
+++ b/dom/svg/nsSVGElement.cpp
@@ -281,17 +281,17 @@ nsSVGElement::BindToTree(nsIDocument* aD
// XBL anonymous content now being bound to the document we should
// render in and due to the hacky way in which we implement the
// interaction of XBL and SVG resources. Once we have a sane
// ownerDocument on XBL anonymous content, this can all go away.
nsAttrValue attrValue;
nsAutoString stringValue;
oldVal->ToString(stringValue);
// Force in data doc, since we already have a style rule
- ParseStyleAttribute(stringValue, attrValue, true);
+ ParseStyleAttribute(stringValue, nullptr, attrValue, true);
// Don't bother going through SetInlineStyleDeclaration; we don't
// want to fire off mutation events or document notifications anyway
bool oldValueSet;
rv = mAttrsAndChildren.SetAndSwapAttr(nsGkAtoms::style, attrValue,
&oldValueSet);
NS_ENSURE_SUCCESS(rv, rv);
}