Bug 1308920: Part 1: Add an equalIgnoringAddonId method to nsIPrincipal. r?bholley draft
authorKris Maglione <maglione.k@gmail.com>
Mon, 31 Oct 2016 15:28:26 -0700
changeset 431895 e2f5194743b5b884a4f500dd46f7dcd7c0bd6e39
parent 431894 1e58a5a4ba4a267fc43959b305dd1eb7640ee30e
child 431896 0f5b119e57164548046c90ec85b287c0d87979a5
push id34143
push usermaglione.k@gmail.com
push dateMon, 31 Oct 2016 22:30:27 +0000
reviewersbholley
bugs1308920
milestone52.0a1
Bug 1308920: Part 1: Add an equalIgnoringAddonId method to nsIPrincipal. r?bholley This is meant as a temporary stopgap until we can stop using origin attributes to store add-on IDs. MozReview-Commit-ID: DHstOTyu7pR
caps/BasePrincipal.cpp
caps/BasePrincipal.h
caps/nsIPrincipal.idl
caps/nsNullPrincipal.h
caps/nsPrincipal.cpp
caps/nsPrincipal.h
caps/nsSystemPrincipal.h
--- a/caps/BasePrincipal.cpp
+++ b/caps/BasePrincipal.cpp
@@ -387,20 +387,21 @@ BasePrincipal::GetOrigin(nsACString& aOr
 
 NS_IMETHODIMP
 BasePrincipal::GetOriginNoSuffix(nsACString& aOrigin)
 {
   return GetOriginInternal(aOrigin);
 }
 
 bool
-BasePrincipal::Subsumes(nsIPrincipal* aOther, DocumentDomainConsideration aConsideration)
+BasePrincipal::Subsumes(nsIPrincipal* aOther, DocumentDomainConsideration aConsideration,
+                        AddonIdConsideration aAddonId)
 {
   MOZ_ASSERT(aOther);
-  return SubsumesInternal(aOther, aConsideration);
+  return SubsumesInternal(aOther, aConsideration, aAddonId);
 }
 
 NS_IMETHODIMP
 BasePrincipal::Equals(nsIPrincipal *aOther, bool *aResult)
 {
   NS_ENSURE_TRUE(aOther, NS_ERROR_INVALID_ARG);
   *aResult = Subsumes(aOther, DontConsiderDocumentDomain) &&
              Cast(aOther)->Subsumes(this, DontConsiderDocumentDomain);
@@ -412,16 +413,25 @@ BasePrincipal::EqualsConsideringDomain(n
 {
   NS_ENSURE_TRUE(aOther, NS_ERROR_INVALID_ARG);
   *aResult = Subsumes(aOther, ConsiderDocumentDomain) &&
              Cast(aOther)->Subsumes(this, ConsiderDocumentDomain);
   return NS_OK;
 }
 
 NS_IMETHODIMP
+BasePrincipal::EqualsIgnoringAddonId(nsIPrincipal *aOther, bool *aResult)
+{
+  NS_ENSURE_TRUE(aOther, NS_ERROR_INVALID_ARG);
+  *aResult = Subsumes(aOther, ConsiderDocumentDomain, DontConsiderAddonId) &&
+             Cast(aOther)->Subsumes(this, ConsiderDocumentDomain, DontConsiderAddonId);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
 BasePrincipal::Subsumes(nsIPrincipal *aOther, bool *aResult)
 {
   NS_ENSURE_TRUE(aOther, NS_ERROR_INVALID_ARG);
   *aResult = Subsumes(aOther, DontConsiderDocumentDomain);
   return NS_OK;
 }
 
 NS_IMETHODIMP
--- a/caps/BasePrincipal.h
+++ b/caps/BasePrincipal.h
@@ -256,22 +256,24 @@ public:
  * We should merge nsJSPrincipals into this class at some point.
  */
 class BasePrincipal : public nsJSPrincipals
 {
 public:
   BasePrincipal();
 
   enum DocumentDomainConsideration { DontConsiderDocumentDomain, ConsiderDocumentDomain};
-  bool Subsumes(nsIPrincipal* aOther, DocumentDomainConsideration aConsideration);
+  enum AddonIdConsideration { DontConsiderAddonId, ConsiderAddonId };
+  bool Subsumes(nsIPrincipal* aOther, DocumentDomainConsideration aConsideration, AddonIdConsideration aAddonId = ConsiderAddonId);
 
   NS_IMETHOD GetOrigin(nsACString& aOrigin) final;
   NS_IMETHOD GetOriginNoSuffix(nsACString& aOrigin) final;
   NS_IMETHOD Equals(nsIPrincipal* other, bool* _retval) final;
   NS_IMETHOD EqualsConsideringDomain(nsIPrincipal* other, bool* _retval) final;
+  NS_IMETHOD EqualsIgnoringAddonId(nsIPrincipal* other, bool* _retval) final;
   NS_IMETHOD Subsumes(nsIPrincipal* other, bool* _retval) final;
   NS_IMETHOD SubsumesConsideringDomain(nsIPrincipal* other, bool* _retval) final;
   NS_IMETHOD CheckMayLoad(nsIURI* uri, bool report, bool allowIfInheritsPrincipal) final;
   NS_IMETHOD GetCsp(nsIContentSecurityPolicy** aCsp) override;
   NS_IMETHOD EnsureCSP(nsIDOMDocument* aDocument, nsIContentSecurityPolicy** aCSP) override;
   NS_IMETHOD GetPreloadCsp(nsIContentSecurityPolicy** aPreloadCSP) override;
   NS_IMETHOD EnsurePreloadCSP(nsIDOMDocument* aDocument, nsIContentSecurityPolicy** aCSP) override;
   NS_IMETHOD GetCspJSON(nsAString& outCSPinJSON) override;
@@ -316,17 +318,17 @@ public:
   virtual PrincipalKind Kind() = 0;
 
   already_AddRefed<BasePrincipal> CloneStrippingUserContextIdAndFirstPartyDomain();
 
 protected:
   virtual ~BasePrincipal();
 
   virtual nsresult GetOriginInternal(nsACString& aOrigin) = 0;
-  virtual bool SubsumesInternal(nsIPrincipal* aOther, DocumentDomainConsideration aConsider) = 0;
+  virtual bool SubsumesInternal(nsIPrincipal* aOther, DocumentDomainConsideration aConsider, AddonIdConsideration aAddonId = ConsiderAddonId) = 0;
 
   // Internal, side-effect-free check to determine whether the concrete
   // principal would allow the load ignoring any common behavior implemented in
   // BasePrincipal::CheckMayLoad.
   virtual bool MayLoadInternal(nsIURI* aURI) = 0;
   friend class ::nsExpandedPrincipal;
 
   // Helper to check whether this principal is associated with an addon that
--- a/caps/nsIPrincipal.idl
+++ b/caps/nsIPrincipal.idl
@@ -31,26 +31,36 @@ interface nsIPrincipal : nsISerializable
      */
     boolean equals(in nsIPrincipal other);
 
     /**
      * Like equals, but takes document.domain changes into account.
      */
     boolean equalsConsideringDomain(in nsIPrincipal other);
 
+    /**
+     * Like equals, but ignores the addonId origin attribute.
+     */
+    boolean equalsIgnoringAddonId(in nsIPrincipal other);
+
     %{C++
     inline bool Equals(nsIPrincipal* aOther) {
       bool equal = false;
       return NS_SUCCEEDED(Equals(aOther, &equal)) && equal;
     }
 
     inline bool EqualsConsideringDomain(nsIPrincipal* aOther) {
       bool equal = false;
       return NS_SUCCEEDED(EqualsConsideringDomain(aOther, &equal)) && equal;
     }
+
+    inline bool EqualsIgnoringAddonId(nsIPrincipal* aOther) {
+      bool equal = false;
+      return NS_SUCCEEDED(EqualsIgnoringAddonId(aOther, &equal)) && equal;
+    }
     %}
 
     /**
      * Returns a hash value for the principal.
      */
     [noscript] readonly attribute unsigned long hashValue;
 
     /**
--- a/caps/nsNullPrincipal.h
+++ b/caps/nsNullPrincipal.h
@@ -59,17 +59,17 @@ public:
 
   virtual nsresult GetScriptLocation(nsACString &aStr) override;
 
   PrincipalKind Kind() override { return eNullPrincipal; }
 
  protected:
   virtual ~nsNullPrincipal() {}
 
-  bool SubsumesInternal(nsIPrincipal* aOther, DocumentDomainConsideration aConsideration) override
+  bool SubsumesInternal(nsIPrincipal* aOther, DocumentDomainConsideration aConsideration, AddonIdConsideration aAddonId = ConsiderAddonId) override
   {
     return aOther == this;
   }
 
   bool MayLoadInternal(nsIURI* aURI) override;
 
   nsCOMPtr<nsIURI> mURI;
 };
--- a/caps/nsPrincipal.cpp
+++ b/caps/nsPrincipal.cpp
@@ -21,16 +21,17 @@
 #include "nsIClassInfoImpl.h"
 #include "nsIProtocolHandler.h"
 #include "nsError.h"
 #include "nsIContentSecurityPolicy.h"
 #include "nsNetCID.h"
 #include "jswrapper.h"
 
 #include "mozilla/dom/nsCSPContext.h"
+#include "mozilla/dom/ChromeUtils.h"
 #include "mozilla/dom/ScriptSettings.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/HashFunctions.h"
 
 #include "nsIAppsService.h"
 
 using namespace mozilla;
 
@@ -183,27 +184,35 @@ nsPrincipal::GetOriginForURI(nsIURI* aUR
 nsresult
 nsPrincipal::GetOriginInternal(nsACString& aOrigin)
 {
   return GetOriginForURI(mCodebase, aOrigin);
 }
 
 bool
 nsPrincipal::SubsumesInternal(nsIPrincipal* aOther,
-                              BasePrincipal::DocumentDomainConsideration aConsideration)
+                              BasePrincipal::DocumentDomainConsideration aConsideration,
+                              BasePrincipal::AddonIdConsideration aAddonIdConsideration)
 {
   MOZ_ASSERT(aOther);
 
   // For nsPrincipal, Subsumes is equivalent to Equals.
   if (aOther == this) {
     return true;
   }
 
-  if (OriginAttributesRef() != Cast(aOther)->OriginAttributesRef()) {
-    return false;
+  if (aAddonIdConsideration == ConsiderAddonId) {
+    if (OriginAttributesRef() != Cast(aOther)->OriginAttributesRef()) {
+      return false;
+    }
+  } else {
+    if (!ChromeUtils::IsOriginAttributesEqualIgnoringAddonId(
+          OriginAttributesRef(), Cast(aOther)->OriginAttributesRef())) {
+      return false;
+    }
   }
 
   // If either the subject or the object has changed its principal by
   // explicitly setting document.domain then the other must also have
   // done so in order to be considered the same origin. This prevents
   // DNS spoofing based on document.domain (154930)
   nsresult rv;
   if (aConsideration == ConsiderDocumentDomain) {
@@ -717,36 +726,37 @@ nsExpandedPrincipal::GetOriginInternal(n
   }
 
   aOrigin.Append("]]");
   return NS_OK;
 }
 
 bool
 nsExpandedPrincipal::SubsumesInternal(nsIPrincipal* aOther,
-                                      BasePrincipal::DocumentDomainConsideration aConsideration)
+                                      BasePrincipal::DocumentDomainConsideration aConsideration,
+                                      BasePrincipal::AddonIdConsideration aAddonIdConsideration)
 {
   // If aOther is an ExpandedPrincipal too, we break it down into its component
   // nsIPrincipals, and check subsumes on each one.
   nsCOMPtr<nsIExpandedPrincipal> expanded = do_QueryInterface(aOther);
   if (expanded) {
     nsTArray< nsCOMPtr<nsIPrincipal> >* otherList;
     expanded->GetWhiteList(&otherList);
     for (uint32_t i = 0; i < otherList->Length(); ++i){
-      if (!SubsumesInternal((*otherList)[i], aConsideration)) {
+      if (!SubsumesInternal((*otherList)[i], aConsideration, aAddonIdConsideration)) {
         return false;
       }
     }
     return true;
   }
 
   // We're dealing with a regular principal. One of our principals must subsume
   // it.
   for (uint32_t i = 0; i < mPrincipals.Length(); ++i) {
-    if (Cast(mPrincipals[i])->Subsumes(aOther, aConsideration)) {
+    if (Cast(mPrincipals[i])->Subsumes(aOther, aConsideration, aAddonIdConsideration)) {
       return true;
     }
   }
 
   return false;
 }
 
 bool
--- a/caps/nsPrincipal.h
+++ b/caps/nsPrincipal.h
@@ -55,17 +55,17 @@ public:
   bool mCodebaseImmutable;
   bool mDomainImmutable;
   bool mInitialized;
   mozilla::Maybe<bool> mIsOnCSSUnprefixingWhitelist; // Lazily-computed
 
 protected:
   virtual ~nsPrincipal();
 
-  bool SubsumesInternal(nsIPrincipal* aOther, DocumentDomainConsideration aConsideration) override;
+  bool SubsumesInternal(nsIPrincipal* aOther, DocumentDomainConsideration aConsideration, AddonIdConsideration aAddonId = ConsiderAddonId) override;
   bool MayLoadInternal(nsIURI* aURI) override;
 };
 
 class nsExpandedPrincipal : public nsIExpandedPrincipal, public mozilla::BasePrincipal
 {
 public:
   nsExpandedPrincipal(nsTArray<nsCOMPtr<nsIPrincipal>> &aWhiteList,
                       const mozilla::PrincipalOriginAttributes& aAttrs);
@@ -85,17 +85,17 @@ public:
   virtual nsresult GetScriptLocation(nsACString &aStr) override;
   nsresult GetOriginInternal(nsACString& aOrigin) override;
 
   PrincipalKind Kind() override { return eExpandedPrincipal; }
 
 protected:
   virtual ~nsExpandedPrincipal();
 
-  bool SubsumesInternal(nsIPrincipal* aOther, DocumentDomainConsideration aConsideration) override;
+  bool SubsumesInternal(nsIPrincipal* aOther, DocumentDomainConsideration aConsideration, AddonIdConsideration aAddonId = ConsiderAddonId) override;
   bool MayLoadInternal(nsIURI* aURI) override;
 
 private:
   nsTArray< nsCOMPtr<nsIPrincipal> > mPrincipals;
 };
 
 #define NS_PRINCIPAL_CONTRACTID "@mozilla.org/principal;1"
 #define NS_PRINCIPAL_CID \
--- a/caps/nsSystemPrincipal.h
+++ b/caps/nsSystemPrincipal.h
@@ -38,17 +38,17 @@ public:
 
   nsSystemPrincipal() {}
 
   virtual nsresult GetScriptLocation(nsACString &aStr) override;
 
 protected:
   virtual ~nsSystemPrincipal(void) {}
 
-  bool SubsumesInternal(nsIPrincipal *aOther, DocumentDomainConsideration aConsideration) override
+  bool SubsumesInternal(nsIPrincipal *aOther, DocumentDomainConsideration aConsideration, AddonIdConsideration aAddonId) override
   {
     return true;
   }
 
   bool MayLoadInternal(nsIURI* aURI) override
   {
     return true;
   }