Bug 1308920: Part 1 - Add an EqualsIgnoringAddonId method to BasePrincipal. 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
--- a/caps/BasePrincipal.cpp
+++ b/caps/BasePrincipal.cpp
@@ -18,16 +18,17 @@
#include "nsPrincipal.h"
#include "nsNetUtil.h"
#include "nsIURIWithPrincipal.h"
#include "nsNullPrincipal.h"
#include "nsScriptSecurityManager.h"
#include "nsServiceManagerUtils.h"
+#include "mozilla/dom/ChromeUtils.h"
#include "mozilla/dom/CSPDictionariesBinding.h"
#include "mozilla/dom/quota/QuotaManager.h"
#include "mozilla/dom/ToJSValue.h"
#include "mozilla/dom/URLSearchParams.h"
namespace mozilla {
using dom::URLParams;
@@ -390,16 +391,25 @@ BasePrincipal::GetOriginNoSuffix(nsACStr
{
return GetOriginInternal(aOrigin);
}
bool
BasePrincipal::Subsumes(nsIPrincipal* aOther, DocumentDomainConsideration aConsideration)
{
MOZ_ASSERT(aOther);
+
+ // Expanded principals handle origin attributes for each of their
+ // sub-principals individually, and system principals are immune to origin
+ // attributes checks, so only do this check for codebase principals.
+ if (Kind() == eCodebasePrincipal &&
+ OriginAttributesRef() != Cast(aOther)->OriginAttributesRef()) {
+ return false;
+ }
+
return SubsumesInternal(aOther, aConsideration);
}
NS_IMETHODIMP
BasePrincipal::Equals(nsIPrincipal *aOther, bool *aResult)
{
NS_ENSURE_TRUE(aOther, NS_ERROR_INVALID_ARG);
*aResult = Subsumes(aOther, DontConsiderDocumentDomain) &&
@@ -411,16 +421,33 @@ NS_IMETHODIMP
BasePrincipal::EqualsConsideringDomain(nsIPrincipal *aOther, bool *aResult)
{
NS_ENSURE_TRUE(aOther, NS_ERROR_INVALID_ARG);
*aResult = Subsumes(aOther, ConsiderDocumentDomain) &&
Cast(aOther)->Subsumes(this, ConsiderDocumentDomain);
return NS_OK;
}
+bool
+BasePrincipal::EqualsIgnoringAddonId(nsIPrincipal *aOther)
+{
+ MOZ_ASSERT(aOther, "Invalid argument");
+ NS_ENSURE_TRUE(aOther, false);
+
+ // Note that this will not work for expanded principals, nor is it intended
+ // to.
+ if (!dom::ChromeUtils::IsOriginAttributesEqualIgnoringAddonId(
+ OriginAttributesRef(), Cast(aOther)->OriginAttributesRef())) {
+ return false;
+ }
+
+ return SubsumesInternal(aOther, DontConsiderDocumentDomain) &&
+ Cast(aOther)->SubsumesInternal(this, DontConsiderDocumentDomain);
+}
+
NS_IMETHODIMP
BasePrincipal::Subsumes(nsIPrincipal *aOther, bool *aResult)
{
NS_ENSURE_TRUE(aOther, NS_ERROR_INVALID_ARG);
*aResult = Subsumes(aOther, DontConsiderDocumentDomain);
return NS_OK;
}
--- a/caps/BasePrincipal.h
+++ b/caps/BasePrincipal.h
@@ -284,16 +284,18 @@ public:
NS_IMETHOD GetAppStatus(uint16_t* aAppStatus) final;
NS_IMETHOD GetAppId(uint32_t* aAppStatus) final;
NS_IMETHOD GetAddonId(nsAString& aAddonId) final;
NS_IMETHOD GetIsInIsolatedMozBrowserElement(bool* aIsInIsolatedMozBrowserElement) final;
NS_IMETHOD GetUnknownAppId(bool* aUnknownAppId) final;
NS_IMETHOD GetUserContextId(uint32_t* aUserContextId) final;
NS_IMETHOD GetPrivateBrowsingId(uint32_t* aPrivateBrowsingId) final;
+ bool EqualsIgnoringAddonId(nsIPrincipal *aOther);
+
virtual bool AddonHasPermission(const nsAString& aPerm);
virtual bool IsOnCSSUnprefixingWhitelist() override { return false; }
virtual bool IsCodebasePrincipal() const { return false; };
static BasePrincipal* Cast(nsIPrincipal* aPrin) { return static_cast<BasePrincipal*>(aPrin); }
static already_AddRefed<BasePrincipal>
--- a/caps/nsPrincipal.cpp
+++ b/caps/nsPrincipal.cpp
@@ -192,20 +192,16 @@ nsPrincipal::SubsumesInternal(nsIPrincip
{
MOZ_ASSERT(aOther);
// For nsPrincipal, Subsumes is equivalent to Equals.
if (aOther == this) {
return true;
}
- if (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) {
// Get .domain on each principal.
nsCOMPtr<nsIURI> thisDomain, otherDomain;