Bug 413161: Make nsIPrincipal::Origin ignore changes to document.domain. r/sr=dveditz
--- a/caps/idl/nsIPrincipal.idl
+++ b/caps/idl/nsIPrincipal.idl
@@ -46,17 +46,17 @@ struct JSContext;
struct JSPrincipals;
%}
interface nsIURI;
[ptr] native JSContext(JSContext);
[ptr] native JSPrincipals(JSPrincipals);
-[scriptable, uuid(7292475e-2821-4602-9d00-228476696428)]
+[scriptable, uuid(b8268b9a-2403-44ed-81e3-614075c92034)]
interface nsIPrincipal : nsISerializable
{
/**
* Values of capabilities for each principal. Order is
* significant: if an operation is performed on a set
* of capabilities, the minimum is computed.
*/
const short ENABLE_DENIED = 1;
@@ -137,19 +137,18 @@ interface nsIPrincipal : nsISerializable
/**
* The domain URI to which this principal pertains.
* This is congruent with HTMLDocument.domain, and may be null.
* Setting this has no effect on the URI.
*/
[noscript] attribute nsIURI domain;
/**
- * The origin of this principal's domain, if non-null, or its
- * codebase URI otherwise. An origin is defined as:
- * scheme + host + port.
+ * The origin of this principal's codebase URI.
+ * An origin is defined as: scheme + host + port.
*/
// XXXcaa this should probably be turned into an nsIURI.
// The system principal's origin should be some caps namespace
// with a chrome URI. All of chrome should probably be the same.
[noscript] readonly attribute string origin;
/**
* Whether this principal is associated with a certificate.
--- a/caps/include/nsPrincipal.h
+++ b/caps/include/nsPrincipal.h
@@ -135,17 +135,16 @@ protected:
// cost of keeping a certificate, this is a good tradeoff though since
// it is very rare that we actually have a certificate.
nsAutoPtr<Certificate> mCert;
DomainPolicy* mSecurityPolicy;
nsCOMPtr<nsIURI> mCodebase;
nsCOMPtr<nsIURI> mDomain;
- nsCOMPtr<nsIURI> mOrigin;
PRPackedBool mTrusted;
PRPackedBool mInitialized;
// If mCodebaseImmutable is true, mCodebase is non-null and immutable
PRPackedBool mCodebaseImmutable;
PRPackedBool mDomainImmutable;
};
--- a/caps/src/nsPrincipal.cpp
+++ b/caps/src/nsPrincipal.cpp
@@ -123,19 +123,16 @@ nsPrincipal::Init(const nsACString& aCer
NS_ENSURE_STATE(!mInitialized);
NS_ENSURE_ARG(!aCertFingerprint.IsEmpty() || aCodebase); // better have one of these.
mInitialized = PR_TRUE;
mCodebase = NS_TryToMakeImmutable(aCodebase);
mCodebaseImmutable = URIIsImmutable(mCodebase);
- // Invalidate our cached origin
- mOrigin = nsnull;
-
nsresult rv;
if (!aCertFingerprint.IsEmpty()) {
rv = SetCertificate(aCertFingerprint, aSubjectName, aPrettyName, aCert);
if (NS_SUCCEEDED(rv)) {
rv = mJSPrincipals.Init(this, mCert->fingerprint);
}
}
else {
@@ -167,51 +164,49 @@ nsPrincipal::GetJSPrincipals(JSContext *
return NS_OK;
}
NS_IMETHODIMP
nsPrincipal::GetOrigin(char **aOrigin)
{
*aOrigin = nsnull;
- if (!mOrigin) {
- nsIURI* uri = mDomain ? mDomain : mCodebase;
- if (uri) {
- mOrigin = NS_GetInnermostURI(uri);
- }
+ nsCOMPtr<nsIURI> origin;
+ if (mCodebase) {
+ origin = NS_GetInnermostURI(mCodebase);
}
- if (!mOrigin) {
+ if (!origin) {
NS_ASSERTION(mCert, "No Domain or Codebase for a non-cert principal");
return NS_ERROR_FAILURE;
}
nsCAutoString hostPort;
// chrome: URLs don't have a meaningful origin, so make
// sure we just get the full spec for them.
// XXX this should be removed in favor of the solution in
// bug 160042.
PRBool isChrome;
- nsresult rv = mOrigin->SchemeIs("chrome", &isChrome);
+ nsresult rv = origin->SchemeIs("chrome", &isChrome);
if (NS_SUCCEEDED(rv) && !isChrome) {
- rv = mOrigin->GetHostPort(hostPort);
+ rv = origin->GetHostPort(hostPort);
}
if (NS_SUCCEEDED(rv) && !isChrome) {
nsCAutoString scheme;
- rv = mOrigin->GetScheme(scheme);
+ rv = origin->GetScheme(scheme);
NS_ENSURE_SUCCESS(rv, rv);
*aOrigin = ToNewCString(scheme + NS_LITERAL_CSTRING("://") + hostPort);
}
else {
// Some URIs (e.g., nsSimpleURI) don't support host. Just
// get the full spec.
nsCAutoString spec;
- rv = mOrigin->GetSpec(spec);
+ rv = origin->GetSpec(spec);
NS_ENSURE_SUCCESS(rv, rv);
*aOrigin = ToNewCString(spec);
}
return *aOrigin ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
}
NS_IMETHODIMP
@@ -560,19 +555,16 @@ nsPrincipal::GetURI(nsIURI** aURI)
return NS_EnsureSafeToReturn(mCodebase, aURI);
}
void
nsPrincipal::SetURI(nsIURI* aURI)
{
mCodebase = NS_TryToMakeImmutable(aURI);
mCodebaseImmutable = URIIsImmutable(mCodebase);
-
- // Invalidate our cached origin
- mOrigin = nsnull;
}
nsresult
nsPrincipal::SetCertificate(const nsACString& aFingerprint,
const nsACString& aSubjectName,
const nsACString& aPrettyName,
nsISupports* aCert)
@@ -671,19 +663,16 @@ NS_IMETHODIMP
nsPrincipal::SetDomain(nsIURI* aDomain)
{
mDomain = NS_TryToMakeImmutable(aDomain);
mDomainImmutable = URIIsImmutable(mDomain);
// Domain has changed, forget cached security policy
SetSecurityPolicy(nsnull);
- // Invalidate our cached origin
- mOrigin = nsnull;
-
return NS_OK;
}
nsresult
nsPrincipal::InitFromPersistent(const char* aPrefName,
const nsCString& aToken,
const nsCString& aSubjectName,
const nsACString& aPrettyName,
@@ -715,19 +704,16 @@ nsPrincipal::InitFromPersistent(const ch
NS_ERROR("Malformed URI in capability.principal preference.");
return rv;
}
NS_TryToSetImmutable(mCodebase);
mCodebaseImmutable = URIIsImmutable(mCodebase);
mTrusted = aTrusted;
-
- // Invalidate our cached origin
- mOrigin = nsnull;
}
rv = mJSPrincipals.Init(this, aToken);
NS_ENSURE_SUCCESS(rv, rv);
//-- Save the preference name
mPrefName = aPrefName;
@@ -1089,18 +1075,16 @@ nsPrincipal::Write(nsIObjectOutputStream
}
rv = NS_WriteOptionalCompoundObject(aStream, mDomain, NS_GET_IID(nsIURI),
PR_TRUE);
if (NS_FAILED(rv)) {
return rv;
}
- // mOrigin is an optimization; don't bother serializing it.
-
rv = aStream->Write8(mTrusted);
if (NS_FAILED(rv)) {
return rv;
}
// mCodebaseImmutable and mDomainImmutable will be recomputed based
// on the deserialized URIs in Read().
--- a/caps/src/nsScriptSecurityManager.cpp
+++ b/caps/src/nsScriptSecurityManager.cpp
@@ -1063,16 +1063,50 @@ nsScriptSecurityManager::CheckSameOrigin
return NS_OK;
/*
** Access tests failed, so now report error.
*/
return NS_ERROR_DOM_PROP_ACCESS_DENIED;
}
+static
+nsresult
+GetPrincipalDomainOrigin(nsIPrincipal* aPrincipal,
+ nsACString& aOrigin)
+{
+ aOrigin.Truncate();
+
+ nsCOMPtr<nsIURI> uri;
+ aPrincipal->GetDomain(getter_AddRefs(uri));
+ if (!uri) {
+ aPrincipal->GetURI(getter_AddRefs(uri));
+ }
+
+ NS_ENSURE_TRUE(uri, NS_ERROR_UNEXPECTED);
+
+ nsCAutoString hostPort;
+
+ nsresult rv = uri->GetHostPort(hostPort);
+ if (NS_SUCCEEDED(rv)) {
+ nsCAutoString scheme;
+ rv = uri->GetScheme(scheme);
+ NS_ENSURE_SUCCESS(rv, rv);
+ aOrigin = scheme + NS_LITERAL_CSTRING("://") + hostPort;
+ }
+ else {
+ // Some URIs (e.g., nsSimpleURI) don't support host. Just
+ // get the full spec.
+ rv = uri->GetSpec(aOrigin);
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
+
+ return NS_OK;
+}
+
nsresult
nsScriptSecurityManager::LookupPolicy(nsIPrincipal* aPrincipal,
ClassInfoData& aClassData,
jsval aProperty,
PRUint32 aAction,
ClassPolicy** aCachedClassPolicy,
SecurityLevel* result)
{
@@ -1094,19 +1128,19 @@ nsScriptSecurityManager::LookupPolicy(ns
if (!dpolicy && mOriginToPolicyMap)
{
//-- Look up the relevant domain policy, if any
#ifdef DEBUG_CAPS_LookupPolicy
printf("DomainLookup ");
#endif
- nsXPIDLCString origin;
- if (NS_FAILED(rv = aPrincipal->GetOrigin(getter_Copies(origin))))
- return rv;
+ nsCAutoString origin;
+ rv = GetPrincipalDomainOrigin(aPrincipal, origin);
+ NS_ENSURE_SUCCESS(rv, rv);
char *start = origin.BeginWriting();
const char *nextToLastDot = nsnull;
const char *lastDot = nsnull;
const char *colon = nsnull;
char *p = start;
//-- search domain (stop at the end of the string or at the 3rd slash)
@@ -2665,23 +2699,23 @@ nsScriptSecurityManager::CheckConfirmDia
return PR_FALSE;
nsXPIDLString noStr;
rv = sStrBundle->GetStringFromName(NS_LITERAL_STRING("No").get(),
getter_Copies(noStr));
if (NS_FAILED(rv))
return PR_FALSE;
- nsXPIDLCString val;
+ nsCAutoString val;
PRBool hasCert;
aPrincipal->GetHasCertificate(&hasCert);
if (hasCert)
rv = aPrincipal->GetPrettyName(val);
else
- rv = aPrincipal->GetOrigin(getter_Copies(val));
+ rv = GetPrincipalDomainOrigin(aPrincipal, val);
if (NS_FAILED(rv))
return PR_FALSE;
NS_ConvertUTF8toUTF16 location(val);
NS_ConvertASCIItoUTF16 capability(aCapability);
FormatCapabilityString(capability);
const PRUnichar *formatStrings[] = { location.get(), capability.get() };
@@ -2786,24 +2820,24 @@ nsScriptSecurityManager::EnableCapabilit
return NS_OK;
PRInt16 canEnable;
if (NS_FAILED(RequestCapability(principal, capability, &canEnable)))
return NS_ERROR_FAILURE;
if (canEnable != nsIPrincipal::ENABLE_GRANTED)
{
- nsXPIDLCString val;
+ nsCAutoString val;
PRBool hasCert;
nsresult rv;
principal->GetHasCertificate(&hasCert);
if (hasCert)
rv = principal->GetPrettyName(val);
else
- rv = principal->GetOrigin(getter_Copies(val));
+ rv = GetPrincipalDomainOrigin(principal, val);
if (NS_FAILED(rv))
return rv;
NS_ConvertUTF8toUTF16 location(val);
NS_ConvertUTF8toUTF16 cap(capability);
const PRUnichar *formatStrings[] = { location.get(), cap.get() };