Bug 489561 - nsPrincipal should cache nsIPrefBranch and codebase_principal_support pref, r+sr=dveditz, +comments from bz

This commit is contained in:
Olli Pettay 2009-06-16 14:00:06 +03:00
parent b4eaa5f247
commit 9a08c869f6

View File

@ -52,13 +52,77 @@
#include "nsHashtable.h" #include "nsHashtable.h"
#include "nsIObjectInputStream.h" #include "nsIObjectInputStream.h"
#include "nsIObjectOutputStream.h" #include "nsIObjectOutputStream.h"
#include "nsIPrefBranch.h" #include "nsIPrefBranch2.h"
#include "nsIPrefService.h" #include "nsIPrefService.h"
#include "nsIClassInfoImpl.h" #include "nsIClassInfoImpl.h"
#include "nsDOMError.h" #include "nsDOMError.h"
#include "nsPrincipal.h" #include "nsPrincipal.h"
class nsCodeBasePrefObserver : nsIObserver
{
public:
nsCodeBasePrefObserver()
{
NS_ASSERTION(!sObserverInstalled, "Shouldn't recreate observer\n");
}
~nsCodeBasePrefObserver()
{
sObserverInstalled = PR_FALSE;
}
void Init()
{
nsCOMPtr<nsIPrefBranch2> prefBranch =
do_GetService(NS_PREFSERVICE_CONTRACTID);
if (prefBranch) {
if (NS_FAILED(prefBranch->GetBoolPref(PrefName(), &sPrefValue))) {
sPrefValue = PR_FALSE;
}
if (NS_SUCCEEDED(prefBranch->AddObserver(PrefName(), this, PR_FALSE))) {
sObserverInstalled = PR_TRUE;
}
}
}
NS_DECL_ISUPPORTS
NS_IMETHOD Observe(nsISupports* aSubject,
const char* aTopic,
const PRUnichar* aData)
{
NS_ASSERTION(!strcmp(aTopic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID),
"Wrong topic!");
NS_ASSERTION(!strcmp(NS_ConvertUTF16toUTF8(aData).get(), PrefName()),
"Wrong pref!");
nsCOMPtr<nsIPrefBranch> prefBranch(do_QueryInterface(aSubject));
if (!prefBranch ||
NS_FAILED(prefBranch->GetBoolPref(PrefName(), &sPrefValue))) {
sPrefValue = PR_FALSE;
}
return NS_OK;
}
const char* PrefName()
{
static const char pref[] = "signed.applets.codebase_principal_support";
return pref;
}
static PRBool PrefValue() { return sPrefValue; }
static PRBool Installed() { return sObserverInstalled; }
protected:
static PRBool sPrefValue;
static PRBool sObserverInstalled;
};
PRBool nsCodeBasePrefObserver::sPrefValue = PR_FALSE;
PRBool nsCodeBasePrefObserver::sObserverInstalled = PR_FALSE;
NS_IMPL_ISUPPORTS1(nsCodeBasePrefObserver, nsIObserver)
static PRBool URIIsImmutable(nsIURI* aURI) static PRBool URIIsImmutable(nsIURI* aURI)
{ {
nsCOMPtr<nsIMutable> mutableObj(do_QueryInterface(aURI)); nsCOMPtr<nsIMutable> mutableObj(do_QueryInterface(aURI));
@ -112,6 +176,13 @@ nsPrincipal::nsPrincipal()
mCodebaseImmutable(PR_FALSE), mCodebaseImmutable(PR_FALSE),
mDomainImmutable(PR_FALSE) mDomainImmutable(PR_FALSE)
{ {
if (!nsCodeBasePrefObserver::Installed()) {
nsRefPtr<nsCodeBasePrefObserver> obs = new nsCodeBasePrefObserver();
if (obs)
obs->Init();
NS_WARN_IF_FALSE(nsCodeBasePrefObserver::Installed(),
"Installing nsCodeBasePrefObserver failed!");
}
} }
nsresult nsresult
@ -425,21 +496,15 @@ nsPrincipal::CanEnableCapability(const char *capability, PRInt16 *result)
// schemes are special and may be able to get extra capabilities // schemes are special and may be able to get extra capabilities
// even with the pref disabled. // even with the pref disabled.
static const char pref[] = "signed.applets.codebase_principal_support"; if (!nsCodeBasePrefObserver::PrefValue()) {
nsCOMPtr<nsIPrefBranch> prefBranch = PRBool mightEnable = PR_FALSE;
do_GetService(NS_PREFSERVICE_CONTRACTID); nsresult rv = mCodebase->SchemeIs("file", &mightEnable);
if (prefBranch) {
PRBool mightEnable;
nsresult rv = prefBranch->GetBoolPref(pref, &mightEnable);
if (NS_FAILED(rv) || !mightEnable) { if (NS_FAILED(rv) || !mightEnable) {
rv = mCodebase->SchemeIs("file", &mightEnable); rv = mCodebase->SchemeIs("resource", &mightEnable);
if (NS_FAILED(rv) || !mightEnable) { if (NS_FAILED(rv) || !mightEnable) {
rv = mCodebase->SchemeIs("resource", &mightEnable); *result = nsIPrincipal::ENABLE_DENIED;
if (NS_FAILED(rv) || !mightEnable) {
*result = nsIPrincipal::ENABLE_DENIED;
return NS_OK; return NS_OK;
}
} }
} }
} }