Bug 1347817 - Principal must always have a valid origin - part 2 - move OriginAttributes to the BasePrincipal, r=bholley
authorAndrea Marchesini <amarchesini@mozilla.com>
Wed, 29 Mar 2017 08:21:03 +0200
changeset 350410 a303ac6e7f6b47b82ea8567eda508ec934381273
parent 350409 ea39a16e4c9796a801679fa49ce5b1b50a75e382
child 350411 918682c3ff30b08ffb127b33f60f2750ccf8d63c
push id31573
push userkwierso@gmail.com
push dateWed, 29 Mar 2017 22:42:07 +0000
treeherdermozilla-central@60d7a0496a36 [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;