Bug 1415352: Part 1b - Store the subject principal when parsing style attributes. r?bz draft
authorKris Maglione <maglione.k@gmail.com>
Thu, 02 Nov 2017 13:36:14 -0700
changeset 694614 333aee0a2a8054cbf7ae7be2b4dd9d31658d21e1
parent 694613 ecb4c80b3afadd4094bf01dad8d6dc63549b934d
child 694615 816463ddf590e757ad64c577e4e3681cb17b74f7
push id88175
push usermaglione.k@gmail.com
push dateTue, 07 Nov 2017 23:59:46 +0000
reviewersbz
bugs1415352
milestone58.0a1
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
dom/base/nsAttrValue.cpp
dom/base/nsAttrValue.h
dom/base/nsStyledElement.cpp
dom/base/nsStyledElement.h
dom/svg/nsSVGElement.cpp
--- 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);
   }