Bug 1347817 - Principal must always have a valid origin - part 2 - move OriginAttributes to the BasePrincipal, r=bholley
☠☠ backed out by 823199ec777a ☠ ☠
authorAndrea Marchesini <amarchesini@mozilla.com>
Wed, 29 Mar 2017 08:21:03 +0200
changeset 350302 c0e8522353bd97100f7b3efc604f1d7e8bd56e0c
parent 350301 a70b549ac35db3b97a0ce3ed7b3b2ea350174c7a
child 350303 d71d95c73542498746ae068c278f444a8cbfe1d6
push id31570
push userryanvm@gmail.com
push dateWed, 29 Mar 2017 13:42:06 +0000
treeherdermozilla-central@6ea713ccc9ab [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbholley
bugs1347817
milestone55.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1347817 - Principal must always have a valid origin - part 2 - move OriginAttributes to the BasePrincipal, r=bholley
caps/BasePrincipal.cpp
caps/BasePrincipal.h
caps/ContentPrincipal.cpp
caps/ContentPrincipal.h
caps/ExpandedPrincipal.cpp
caps/ExpandedPrincipal.h
caps/NullPrincipal.cpp
caps/SystemPrincipal.cpp
--- a/caps/BasePrincipal.cpp
+++ b/caps/BasePrincipal.cpp
@@ -25,38 +25,43 @@
 #include "mozilla/dom/ChromeUtils.h"
 #include "mozilla/dom/CSPDictionariesBinding.h"
 #include "mozilla/dom/ToJSValue.h"
 
 namespace mozilla {
 
 BasePrincipal::BasePrincipal(PrincipalKind aKind)
   : mKind(aKind)
-  , mDomainSet(false)
+  , mHasExplicitDomain(false)
+  , mInitialized(false)
 {}
 
 BasePrincipal::~BasePrincipal()
 {}
 
 NS_IMETHODIMP
 BasePrincipal::GetOrigin(nsACString& aOrigin)
 {
+  MOZ_ASSERT(mInitialized);
+
   nsresult rv = GetOriginNoSuffix(aOrigin);
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsAutoCString suffix;
   rv = GetOriginSuffix(suffix);
   NS_ENSURE_SUCCESS(rv, rv);
   aOrigin.Append(suffix);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 BasePrincipal::GetOriginNoSuffix(nsACString& aOrigin)
 {
+  MOZ_ASSERT(mInitialized);
+
   if (mOriginNoSuffix) {
     return mOriginNoSuffix->ToUTF8String(aOrigin);
   }
   return GetOriginNoSuffixInternal(aOrigin);
 }
 
 bool
 BasePrincipal::Subsumes(nsIPrincipal* aOther, DocumentDomainConsideration aConsideration)
@@ -451,18 +456,21 @@ BasePrincipal::AddonAllowsLoad(nsIURI* a
   NS_ENSURE_TRUE(aps, false);
 
   bool allowed = false;
   nsresult rv = aps->AddonMayLoadURI(addonId, aURI, aExplicit, &allowed);
   return NS_SUCCEEDED(rv) && allowed;
 }
 
 void
-BasePrincipal::FinishInit()
+BasePrincipal::FinishInit(const OriginAttributes& aOriginAttributes)
 {
+  mInitialized = true;
+  mOriginAttributes = aOriginAttributes;
+
   // First compute the origin suffix since it's infallible.
   nsAutoCString originSuffix;
   mOriginAttributes.CreateSuffix(originSuffix);
   mOriginSuffix = NS_Atomize(originSuffix);
 
   // Then compute the origin without the suffix.
   nsAutoCString originNoSuffix;
   nsresult rv = GetOriginNoSuffixInternal(originNoSuffix);
--- a/caps/BasePrincipal.h
+++ b/caps/BasePrincipal.h
@@ -110,28 +110,37 @@ protected:
   virtual bool SubsumesInternal(nsIPrincipal* aOther, DocumentDomainConsideration aConsider) = 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 ::ExpandedPrincipal;
 
+  void
+  SetHasExplicitDomain()
+  {
+    mHasExplicitDomain = true;
+  }
+
   // This function should be called as the last step of the initialization of the
   // principal objects.  It's typically called as the last step from the Init()
   // method of the child classes.
-  void FinishInit();
+  void FinishInit(const OriginAttributes& aOriginAttributes);
 
   nsCOMPtr<nsIContentSecurityPolicy> mCSP;
   nsCOMPtr<nsIContentSecurityPolicy> mPreloadCSP;
   nsCOMPtr<nsIAtom> mOriginNoSuffix;
   nsCOMPtr<nsIAtom> mOriginSuffix;
+
+private:
   OriginAttributes mOriginAttributes;
   PrincipalKind mKind;
-  bool mDomainSet;
+  bool mHasExplicitDomain;
+  bool mInitialized;
 };
 
 inline bool
 BasePrincipal::FastEquals(nsIPrincipal* aOther)
 {
   auto other = Cast(aOther);
   if (Kind() != other->Kind()) {
     // Principals of different kinds can't be equal.
@@ -164,17 +173,17 @@ BasePrincipal::FastEquals(nsIPrincipal* 
 }
 
 inline bool
 BasePrincipal::FastEqualsConsideringDomain(nsIPrincipal* aOther)
 {
   // If neither of the principals have document.domain set, we use the fast path
   // in Equals().  Otherwise, we fall back to the slow path below.
   auto other = Cast(aOther);
-  if (!mDomainSet && !other->mDomainSet) {
+  if (!mHasExplicitDomain && !other->mHasExplicitDomain) {
     return FastEquals(aOther);
   }
 
   return Subsumes(aOther, ConsiderDocumentDomain) &&
          other->Subsumes(this, ConsiderDocumentDomain);
 }
 
 inline bool
@@ -200,17 +209,17 @@ BasePrincipal::FastSubsumes(nsIPrincipal
 }
 
 inline bool
 BasePrincipal::FastSubsumesConsideringDomain(nsIPrincipal* aOther)
 {
   // If neither of the principals have document.domain set, we hand off to
   // FastSubsumes() which has fast paths for some special cases. Otherwise, we fall
   // back to the slow path below.
-  if (!mDomainSet && !Cast(aOther)->mDomainSet) {
+  if (!mHasExplicitDomain && !Cast(aOther)->mHasExplicitDomain) {
     return FastSubsumes(aOther);
   }
 
   return Subsumes(aOther, ConsiderDocumentDomain);
 }
 
 inline bool
 BasePrincipal::FastSubsumesConsideringDomainIgnoringFPD(nsIPrincipal* aOther)
--- a/caps/ContentPrincipal.cpp
+++ b/caps/ContentPrincipal.cpp
@@ -77,55 +77,50 @@ ContentPrincipal::InitializeStatics()
                                "signed.applets.codebase_principal_support",
                                false);
 }
 
 ContentPrincipal::ContentPrincipal()
   : BasePrincipal(eCodebasePrincipal)
   , mCodebaseImmutable(false)
   , mDomainImmutable(false)
-  , mInitialized(false)
 {
 }
 
 ContentPrincipal::~ContentPrincipal()
 {
   // let's clear the principal within the csp to avoid a tangling pointer
   if (mCSP) {
     static_cast<nsCSPContext*>(mCSP.get())->clearLoadingPrincipal();
   }
 }
 
 nsresult
 ContentPrincipal::Init(nsIURI *aCodebase,
                        const OriginAttributes& aOriginAttributes)
 {
-  NS_ENSURE_STATE(!mInitialized);
   NS_ENSURE_ARG(aCodebase);
 
-  mInitialized = true;
-
   // Assert that the URI we get here isn't any of the schemes that we know we
   // should not get here.  These schemes always either inherit their principal
   // or fall back to a null principal.  These are schemes which return
   // URI_INHERITS_SECURITY_CONTEXT from their protocol handler's
   // GetProtocolFlags function.
   bool hasFlag;
   Unused << hasFlag; // silence possible compiler warnings.
   MOZ_DIAGNOSTIC_ASSERT(
       NS_SUCCEEDED(NS_URIChainHasFlags(aCodebase,
                                        nsIProtocolHandler::URI_INHERITS_SECURITY_CONTEXT,
                                        &hasFlag)) &&
       !hasFlag);
 
   mCodebase = NS_TryToMakeImmutable(aCodebase);
   mCodebaseImmutable = URIIsImmutable(mCodebase);
-  mOriginAttributes = aOriginAttributes;
 
-  FinishInit();
+  FinishInit(aOriginAttributes);
 
   return NS_OK;
 }
 
 nsresult
 ContentPrincipal::GetScriptLocation(nsACString &aStr)
 {
   return mCodebase->GetSpec(aStr);
@@ -367,17 +362,17 @@ ContentPrincipal::GetDomain(nsIURI** aDo
   return NS_EnsureSafeToReturn(mDomain, aDomain);
 }
 
 NS_IMETHODIMP
 ContentPrincipal::SetDomain(nsIURI* aDomain)
 {
   mDomain = NS_TryToMakeImmutable(aDomain);
   mDomainImmutable = URIIsImmutable(mDomain);
-  mDomainSet = true;
+  SetHasExplicitDomain();
 
   // Recompute all wrappers between compartments using this principal and other
   // non-chrome compartments.
   AutoSafeJSContext cx;
   JSPrincipals *principals = nsJSPrincipals::get(static_cast<nsIPrincipal*>(this));
   bool success = js::RecomputeWrappers(cx, js::ContentCompartmentsOnly(),
                                        js::CompartmentsWithPrincipals(principals));
   NS_ENSURE_TRUE(success, NS_ERROR_FAILURE);
--- a/caps/ContentPrincipal.h
+++ b/caps/ContentPrincipal.h
@@ -42,17 +42,16 @@ public:
    */
   static void InitializeStatics();
 
   nsCOMPtr<nsIURI> mDomain;
   nsCOMPtr<nsIURI> mCodebase;
   // If mCodebaseImmutable is true, mCodebase is non-null and immutable
   bool mCodebaseImmutable;
   bool mDomainImmutable;
-  bool mInitialized;
 
 protected:
   virtual ~ContentPrincipal();
 
   bool SubsumesInternal(nsIPrincipal* aOther,
                         DocumentDomainConsideration aConsideration) override;
   bool MayLoadInternal(nsIURI* aURI) override;
 
--- a/caps/ExpandedPrincipal.cpp
+++ b/caps/ExpandedPrincipal.cpp
@@ -38,38 +38,36 @@ struct OriginComparator
     NS_ENSURE_SUCCESS(rv, false);
     nsAutoCString originB;
     rv = b->GetOrigin(originB);
     NS_ENSURE_SUCCESS(rv, false);
     return a == b;
   }
 };
 
-ExpandedPrincipal::ExpandedPrincipal(nsTArray<nsCOMPtr<nsIPrincipal>> &aWhiteList,
-                                     const OriginAttributes& aAttrs)
+ExpandedPrincipal::ExpandedPrincipal(nsTArray<nsCOMPtr<nsIPrincipal>> &aWhiteList)
   : BasePrincipal(eExpandedPrincipal)
 {
   // We force the principals to be sorted by origin so that ExpandedPrincipal
   // origins can have a canonical form.
   OriginComparator c;
   for (size_t i = 0; i < aWhiteList.Length(); ++i) {
     mPrincipals.InsertElementSorted(aWhiteList[i], c);
   }
-  mOriginAttributes = aAttrs;
 }
 
 ExpandedPrincipal::~ExpandedPrincipal()
 { }
 
 already_AddRefed<ExpandedPrincipal>
 ExpandedPrincipal::Create(nsTArray<nsCOMPtr<nsIPrincipal>>& aWhiteList,
                           const OriginAttributes& aAttrs)
 {
-  RefPtr<ExpandedPrincipal> ep = new ExpandedPrincipal(aWhiteList, aAttrs);
-  ep->FinishInit();
+  RefPtr<ExpandedPrincipal> ep = new ExpandedPrincipal(aWhiteList);
+  ep->FinishInit(aAttrs);
   return ep.forget();
 }
 
 NS_IMETHODIMP
 ExpandedPrincipal::GetDomain(nsIURI** aDomain)
 {
   *aDomain = nullptr;
   return NS_OK;
--- a/caps/ExpandedPrincipal.h
+++ b/caps/ExpandedPrincipal.h
@@ -10,19 +10,16 @@
 #include "nsJSPrincipals.h"
 #include "nsTArray.h"
 #include "nsNetUtil.h"
 #include "mozilla/BasePrincipal.h"
 
 class ExpandedPrincipal : public nsIExpandedPrincipal
                         , public mozilla::BasePrincipal
 {
-  ExpandedPrincipal(nsTArray<nsCOMPtr<nsIPrincipal>> &aWhiteList,
-                    const mozilla::OriginAttributes& aAttrs);
-
 public:
   static already_AddRefed<ExpandedPrincipal>
   Create(nsTArray<nsCOMPtr<nsIPrincipal>>& aWhiteList,
          const mozilla::OriginAttributes& aAttrs);
 
   NS_DECL_NSIEXPANDEDPRINCIPAL
   NS_DECL_NSISERIALIZABLE
 
@@ -35,16 +32,18 @@ public:
   NS_IMETHOD SetDomain(nsIURI* aDomain) override;
   NS_IMETHOD GetBaseDomain(nsACString& aBaseDomain) override;
   NS_IMETHOD GetAddonId(nsAString& aAddonId) override;
   virtual bool AddonHasPermission(const nsAString& aPerm) override;
   virtual nsresult GetScriptLocation(nsACString &aStr) override;
   nsresult GetOriginNoSuffixInternal(nsACString& aOrigin) override;
 
 protected:
+  explicit ExpandedPrincipal(nsTArray<nsCOMPtr<nsIPrincipal>> &aWhiteList);
+
   virtual ~ExpandedPrincipal();
 
   bool SubsumesInternal(nsIPrincipal* aOther,
                         DocumentDomainConsideration aConsideration) override;
 
   bool MayLoadInternal(nsIURI* aURI) override;
 
 private:
--- a/caps/NullPrincipal.cpp
+++ b/caps/NullPrincipal.cpp
@@ -65,33 +65,31 @@ NullPrincipal::Create(const OriginAttrib
   MOZ_RELEASE_ASSERT(NS_SUCCEEDED(rv));
 
   return nullPrin.forget();
 }
 
 nsresult
 NullPrincipal::Init(const OriginAttributes& aOriginAttributes, nsIURI* aURI)
 {
-  mOriginAttributes = aOriginAttributes;
-
   if (aURI) {
     nsAutoCString scheme;
     nsresult rv = aURI->GetScheme(scheme);
     NS_ENSURE_SUCCESS(rv, rv);
 
     NS_ENSURE_TRUE(scheme.EqualsLiteral(NS_NULLPRINCIPAL_SCHEME),
                    NS_ERROR_NOT_AVAILABLE);
 
     mURI = aURI;
   } else {
     mURI = NullPrincipalURI::Create();
     NS_ENSURE_TRUE(mURI, NS_ERROR_NOT_AVAILABLE);
   }
 
-  FinishInit();
+  FinishInit(aOriginAttributes);
 
   return NS_OK;
 }
 
 nsresult
 NullPrincipal::GetScriptLocation(nsACString &aStr)
 {
   return mURI->GetSpec(aStr);
--- a/caps/SystemPrincipal.cpp
+++ b/caps/SystemPrincipal.cpp
@@ -30,17 +30,17 @@ NS_IMPL_CI_INTERFACE_GETTER(SystemPrinci
                             nsISerializable)
 
 #define SYSTEM_PRINCIPAL_SPEC "[System Principal]"
 
 already_AddRefed<SystemPrincipal>
 SystemPrincipal::Create()
 {
   RefPtr<SystemPrincipal> sp = new SystemPrincipal();
-  sp->FinishInit();
+  sp->FinishInit(OriginAttributes());
   return sp.forget();
 }
 
 nsresult
 SystemPrincipal::GetScriptLocation(nsACString &aStr)
 {
     aStr.AssignLiteral(SYSTEM_PRINCIPAL_SPEC);
     return NS_OK;