diff --git a/caps/BasePrincipal.cpp b/caps/BasePrincipal.cpp index e7792d019634..23e563545f83 100644 --- a/caps/BasePrincipal.cpp +++ b/caps/BasePrincipal.cpp @@ -297,11 +297,12 @@ BasePrincipal::~BasePrincipal() NS_IMETHODIMP BasePrincipal::GetOrigin(nsACString& aOrigin) { - nsresult rv = GetOriginInternal(aOrigin); + nsresult rv = GetOriginNoSuffix(aOrigin); NS_ENSURE_SUCCESS(rv, rv); nsAutoCString suffix; - mOriginAttributes.CreateSuffix(suffix); + rv = GetOriginSuffix(suffix); + NS_ENSURE_SUCCESS(rv, rv); aOrigin.Append(suffix); return NS_OK; } @@ -309,6 +310,9 @@ BasePrincipal::GetOrigin(nsACString& aOrigin) NS_IMETHODIMP BasePrincipal::GetOriginNoSuffix(nsACString& aOrigin) { + if (mOriginNoSuffix) { + return mOriginNoSuffix->ToUTF8String(aOrigin); + } return GetOriginInternal(aOrigin); } @@ -532,8 +536,8 @@ BasePrincipal::GetOriginAttributes(JSContext* aCx, JS::MutableHandle NS_IMETHODIMP BasePrincipal::GetOriginSuffix(nsACString& aOriginAttributes) { - mOriginAttributes.CreateSuffix(aOriginAttributes); - return NS_OK; + MOZ_ASSERT(mOriginSuffix); + return mOriginSuffix->ToUTF8String(aOriginAttributes); } NS_IMETHODIMP @@ -694,4 +698,25 @@ BasePrincipal::AddonAllowsLoad(nsIURI* aURI, bool aExplicit /* = false */) return NS_SUCCEEDED(rv) && allowed; } +void +BasePrincipal::FinishInit() +{ + // 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 = GetOriginInternal(originNoSuffix); + if (NS_FAILED(rv)) { + // If GetOriginInternal fails, we will get a null atom for mOriginNoSuffix, + // which we deal with anywhere mOriginNoSuffix is used. + // Once this is made infallible we can remove those null checks. + mOriginNoSuffix = nullptr; + return; + } + mOriginNoSuffix = NS_Atomize(originNoSuffix); +} + } // namespace mozilla diff --git a/caps/BasePrincipal.h b/caps/BasePrincipal.h index e432a7823cd7..87def29ee870 100644 --- a/caps/BasePrincipal.h +++ b/caps/BasePrincipal.h @@ -279,8 +279,15 @@ protected: virtual bool MayLoadInternal(nsIURI* aURI) = 0; friend class ::nsExpandedPrincipal; + // 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(); + nsCOMPtr mCSP; nsCOMPtr mPreloadCSP; + nsCOMPtr mOriginNoSuffix; + nsCOMPtr mOriginSuffix; OriginAttributes mOriginAttributes; PrincipalKind mKind; }; diff --git a/caps/nsExpandedPrincipal.cpp b/caps/nsExpandedPrincipal.cpp index ae44ff9082bb..9a06abe874d7 100644 --- a/caps/nsExpandedPrincipal.cpp +++ b/caps/nsExpandedPrincipal.cpp @@ -59,6 +59,15 @@ nsExpandedPrincipal::nsExpandedPrincipal(nsTArray> &aWhit nsExpandedPrincipal::~nsExpandedPrincipal() { } +already_AddRefed +nsExpandedPrincipal::Create(nsTArray>& aWhiteList, + const OriginAttributes& aAttrs) +{ + RefPtr ep = new nsExpandedPrincipal(aWhiteList, aAttrs); + ep->FinishInit(); + return ep.forget(); +} + NS_IMETHODIMP nsExpandedPrincipal::GetDomain(nsIURI** aDomain) { diff --git a/caps/nsExpandedPrincipal.h b/caps/nsExpandedPrincipal.h index eff357fa4edc..360f83ce65d0 100644 --- a/caps/nsExpandedPrincipal.h +++ b/caps/nsExpandedPrincipal.h @@ -15,10 +15,14 @@ class nsExpandedPrincipal : public nsIExpandedPrincipal , public mozilla::BasePrincipal { -public: nsExpandedPrincipal(nsTArray> &aWhiteList, const mozilla::OriginAttributes& aAttrs); +public: + static already_AddRefed + Create(nsTArray>& aWhiteList, + const mozilla::OriginAttributes& aAttrs); + NS_DECL_NSIEXPANDEDPRINCIPAL NS_DECL_NSISERIALIZABLE NS_IMETHOD_(MozExternalRefCountType) AddRef() override { return nsJSPrincipals::AddRef(); }; diff --git a/caps/nsNullPrincipal.cpp b/caps/nsNullPrincipal.cpp index 203174c06e35..0610e2ebe533 100644 --- a/caps/nsNullPrincipal.cpp +++ b/caps/nsNullPrincipal.cpp @@ -86,6 +86,8 @@ nsNullPrincipal::Init(const OriginAttributes& aOriginAttributes, nsIURI* aURI) NS_ENSURE_TRUE(mURI, NS_ERROR_NOT_AVAILABLE); } + FinishInit(); + return NS_OK; } diff --git a/caps/nsPrincipal.cpp b/caps/nsPrincipal.cpp index 096f4f7fcc52..bf740acde6b1 100644 --- a/caps/nsPrincipal.cpp +++ b/caps/nsPrincipal.cpp @@ -117,6 +117,8 @@ nsPrincipal::Init(nsIURI *aCodebase, const OriginAttributes& aOriginAttributes) mCodebaseImmutable = URIIsImmutable(mCodebase); mOriginAttributes = aOriginAttributes; + FinishInit(); + return NS_OK; } diff --git a/caps/nsScriptSecurityManager.cpp b/caps/nsScriptSecurityManager.cpp index 489e36809241..e1470578c9d2 100644 --- a/caps/nsScriptSecurityManager.cpp +++ b/caps/nsScriptSecurityManager.cpp @@ -1314,7 +1314,7 @@ nsresult nsScriptSecurityManager::Init() NS_ENSURE_SUCCESS(rv, rv); // Create our system principal singleton - RefPtr system = new nsSystemPrincipal(); + RefPtr system = nsSystemPrincipal::Create(); mSystemPrincipal = system; diff --git a/caps/nsSystemPrincipal.cpp b/caps/nsSystemPrincipal.cpp index 5a879f347d62..94cbeecc29a5 100644 --- a/caps/nsSystemPrincipal.cpp +++ b/caps/nsSystemPrincipal.cpp @@ -31,6 +31,14 @@ NS_IMPL_CI_INTERFACE_GETTER(nsSystemPrincipal, #define SYSTEM_PRINCIPAL_SPEC "[System Principal]" +already_AddRefed +nsSystemPrincipal::Create() +{ + RefPtr sp = new nsSystemPrincipal(); + sp->FinishInit(); + return sp.forget(); +} + nsresult nsSystemPrincipal::GetScriptLocation(nsACString &aStr) { diff --git a/caps/nsSystemPrincipal.h b/caps/nsSystemPrincipal.h index 8ff952d7f45f..2dd6a0f58ef1 100644 --- a/caps/nsSystemPrincipal.h +++ b/caps/nsSystemPrincipal.h @@ -22,7 +22,14 @@ class nsSystemPrincipal final : public mozilla::BasePrincipal { + nsSystemPrincipal() + : BasePrincipal(eSystemPrincipal) + { + } + public: + static already_AddRefed Create(); + NS_DECL_NSISERIALIZABLE NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr) override; NS_IMETHOD GetHashValue(uint32_t* aHashValue) override; @@ -37,11 +44,6 @@ public: NS_IMETHOD GetAddonId(nsAString& aAddonId) override; nsresult GetOriginInternal(nsACString& aOrigin) override; - nsSystemPrincipal() - : BasePrincipal(eSystemPrincipal) - { - } - virtual nsresult GetScriptLocation(nsACString &aStr) override; protected: diff --git a/ipc/glue/BackgroundUtils.cpp b/ipc/glue/BackgroundUtils.cpp index 28f6ed90d3bf..341b9ecba22a 100644 --- a/ipc/glue/BackgroundUtils.cpp +++ b/ipc/glue/BackgroundUtils.cpp @@ -112,7 +112,8 @@ PrincipalInfoToPrincipal(const PrincipalInfo& aPrincipalInfo, whitelist.AppendElement(wlPrincipal); } - RefPtr expandedPrincipal = new nsExpandedPrincipal(whitelist, info.attrs()); + RefPtr expandedPrincipal = + nsExpandedPrincipal::Create(whitelist, info.attrs()); if (!expandedPrincipal) { NS_WARNING("could not instantiate expanded principal"); return nullptr; diff --git a/js/xpconnect/src/Sandbox.cpp b/js/xpconnect/src/Sandbox.cpp index d922b74ac7ef..d52c408660bc 100644 --- a/js/xpconnect/src/Sandbox.cpp +++ b/js/xpconnect/src/Sandbox.cpp @@ -1439,8 +1439,8 @@ GetExpandedPrincipal(JSContext* cx, HandleObject arrayObj, } } - nsCOMPtr result = - new nsExpandedPrincipal(allowedDomains, attrs.ref()); + RefPtr result = + nsExpandedPrincipal::Create(allowedDomains, attrs.ref()); result.forget(out); return true; } diff --git a/js/xpconnect/src/XPCWrappedNativeScope.cpp b/js/xpconnect/src/XPCWrappedNativeScope.cpp index 7babc6b3bb0a..c3c87d76a795 100644 --- a/js/xpconnect/src/XPCWrappedNativeScope.cpp +++ b/js/xpconnect/src/XPCWrappedNativeScope.cpp @@ -295,13 +295,15 @@ XPCWrappedNativeScope::EnsureContentXBLScope(JSContext* cx) MOZ_ASSERT(!nsContentUtils::IsExpandedPrincipal(principal)); nsTArray> principalAsArray(1); principalAsArray.AppendElement(principal); - nsCOMPtr ep = - new nsExpandedPrincipal(principalAsArray, - principal->OriginAttributesRef()); + RefPtr ep = + nsExpandedPrincipal::Create(principalAsArray, + principal->OriginAttributesRef()); // Create the sandbox. RootedValue v(cx); - nsresult rv = CreateSandboxObject(cx, &v, ep, options); + nsresult rv = CreateSandboxObject(cx, &v, + static_cast(ep), + options); NS_ENSURE_SUCCESS(rv, nullptr); mContentXBLScope = &v.toObject();