From 9da6f0843dd65ad2f625872f85bb4ad7f8258606 Mon Sep 17 00:00:00 2001 From: Olli Pettay Date: Tue, 16 Jun 2009 14:00:06 +0300 Subject: [PATCH] Bug 489561 - nsPrincipal should cache nsIPrefBranch and codebase_principal_support pref, r+sr=dveditz, +comments from bz --- caps/src/nsPrincipal.cpp | 91 ++++++++++++++++++++++++++++++++++------ 1 file changed, 78 insertions(+), 13 deletions(-) diff --git a/caps/src/nsPrincipal.cpp b/caps/src/nsPrincipal.cpp index 2d2c7509ffb..42d75a3f149 100644 --- a/caps/src/nsPrincipal.cpp +++ b/caps/src/nsPrincipal.cpp @@ -52,13 +52,77 @@ #include "nsHashtable.h" #include "nsIObjectInputStream.h" #include "nsIObjectOutputStream.h" -#include "nsIPrefBranch.h" +#include "nsIPrefBranch2.h" #include "nsIPrefService.h" #include "nsIClassInfoImpl.h" #include "nsDOMError.h" #include "nsPrincipal.h" +class nsCodeBasePrefObserver : nsIObserver +{ +public: + nsCodeBasePrefObserver() + { + NS_ASSERTION(!sObserverInstalled, "Shouldn't recreate observer\n"); + } + ~nsCodeBasePrefObserver() + { + sObserverInstalled = PR_FALSE; + } + + void Init() + { + nsCOMPtr 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 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) { nsCOMPtr mutableObj(do_QueryInterface(aURI)); @@ -112,6 +176,13 @@ nsPrincipal::nsPrincipal() mCodebaseImmutable(PR_FALSE), mDomainImmutable(PR_FALSE) { + if (!nsCodeBasePrefObserver::Installed()) { + nsRefPtr obs = new nsCodeBasePrefObserver(); + if (obs) + obs->Init(); + NS_WARN_IF_FALSE(nsCodeBasePrefObserver::Installed(), + "Installing nsCodeBasePrefObserver failed!"); + } } nsresult @@ -425,21 +496,15 @@ nsPrincipal::CanEnableCapability(const char *capability, PRInt16 *result) // schemes are special and may be able to get extra capabilities // even with the pref disabled. - static const char pref[] = "signed.applets.codebase_principal_support"; - nsCOMPtr prefBranch = - do_GetService(NS_PREFSERVICE_CONTRACTID); - if (prefBranch) { - PRBool mightEnable; - nsresult rv = prefBranch->GetBoolPref(pref, &mightEnable); + if (!nsCodeBasePrefObserver::PrefValue()) { + PRBool mightEnable = PR_FALSE; + nsresult rv = mCodebase->SchemeIs("file", &mightEnable); if (NS_FAILED(rv) || !mightEnable) { - rv = mCodebase->SchemeIs("file", &mightEnable); + rv = mCodebase->SchemeIs("resource", &mightEnable); if (NS_FAILED(rv) || !mightEnable) { - rv = mCodebase->SchemeIs("resource", &mightEnable); - if (NS_FAILED(rv) || !mightEnable) { - *result = nsIPrincipal::ENABLE_DENIED; + *result = nsIPrincipal::ENABLE_DENIED; - return NS_OK; - } + return NS_OK; } } }