From cc155c01091a40d2f85a6af6bf2f2fe017f2e64b Mon Sep 17 00:00:00 2001 From: "bzbarsky%mit.edu" Date: Thu, 22 Jun 2006 02:19:49 +0000 Subject: [PATCH] Allow about: modules to just set a flag to force script execution to be allowed for particular about: URIs, instead of hardcoding checks in the security manager. Bug 341313, r=darin, sr=jst git-svn-id: svn://10.0.0.236/trunk@200562 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/caps/src/nsScriptSecurityManager.cpp | 27 ++++++++++++------- .../about/public/nsAboutProtocolUtils.h | 16 +++++++++++ .../protocol/about/public/nsIAboutModule.idl | 6 +++++ .../about/src/nsAboutProtocolHandler.cpp | 22 ++------------- .../about/src/nsAboutProtocolHandler.h | 3 --- .../protocol/about/src/nsAboutRedirector.cpp | 27 ++++++++++++------- mozilla/xpfe/appshell/src/nsAbout.cpp | 2 +- 7 files changed, 60 insertions(+), 43 deletions(-) diff --git a/mozilla/caps/src/nsScriptSecurityManager.cpp b/mozilla/caps/src/nsScriptSecurityManager.cpp index b6e4f507d4f..df36a8d470e 100644 --- a/mozilla/caps/src/nsScriptSecurityManager.cpp +++ b/mozilla/caps/src/nsScriptSecurityManager.cpp @@ -1619,19 +1619,28 @@ nsScriptSecurityManager::CanExecuteScripts(JSContext* cx, } // OK, the docshell doesn't have script execution explicitly disabled. - // Check whether our URI is "about:". If it is, we need to allow JS to - // run... In this case, don't apply the JS enabled pref or policies. + // Check whether our URI is an "about:" URI that allows scripts. If it is, + // we need to allow JS to run. In this case, don't apply the JS enabled + // pref or policies. On failures, just press on and don't do this special + // case. nsCOMPtr principalURI; aPrincipal->GetURI(getter_AddRefs(principalURI)); if (principalURI) { - nsCAutoString spec; - principalURI->GetSpec(spec); - if (spec.EqualsLiteral("about:") || - StringBeginsWith(spec, NS_LITERAL_CSTRING("about:neterror?"))) - { - *result = PR_TRUE; - return NS_OK; + PRBool isAbout; + rv = principalURI->SchemeIs("about", &isAbout); + if (NS_SUCCEEDED(rv) && isAbout) { + nsCOMPtr module; + rv = NS_GetAboutModule(principalURI, getter_AddRefs(module)); + if (NS_SUCCEEDED(rv)) { + PRUint32 flags; + rv = module->GetURIFlags(principalURI, &flags); + if (NS_SUCCEEDED(rv) && + (flags & nsIAboutModule::ALLOW_SCRIPT)) { + *result = PR_TRUE; + return NS_OK; + } + } } } diff --git a/mozilla/netwerk/protocol/about/public/nsAboutProtocolUtils.h b/mozilla/netwerk/protocol/about/public/nsAboutProtocolUtils.h index 20301a00b9f..c059a1c4527 100644 --- a/mozilla/netwerk/protocol/about/public/nsAboutProtocolUtils.h +++ b/mozilla/netwerk/protocol/about/public/nsAboutProtocolUtils.h @@ -37,6 +37,7 @@ #include "nsIURI.h" #include "nsString.h" #include "nsReadableUtils.h" +#include "nsIAboutModule.h" inline nsresult NS_GetAboutModuleName(nsIURI *aAboutURI, nsCString& aModule) @@ -62,3 +63,18 @@ NS_GetAboutModuleName(nsIURI *aAboutURI, nsCString& aModule) ToLowerCase(aModule); return NS_OK; } + +inline nsresult +NS_GetAboutModule(nsIURI *aAboutURI, nsIAboutModule** aModule) +{ + NS_PRECONDITION(aAboutURI, "Must have URI"); + + nsCAutoString contractID; + nsresult rv = NS_GetAboutModuleName(aAboutURI, contractID); + if (NS_FAILED(rv)) return rv; + + // look up a handler to deal with "what" + contractID.Insert(NS_LITERAL_CSTRING(NS_ABOUT_MODULE_CONTRACTID_PREFIX), 0); + + return CallGetService(contractID.get(), aModule); +} diff --git a/mozilla/netwerk/protocol/about/public/nsIAboutModule.idl b/mozilla/netwerk/protocol/about/public/nsIAboutModule.idl index 498077a9619..f89ab4b4430 100644 --- a/mozilla/netwerk/protocol/about/public/nsIAboutModule.idl +++ b/mozilla/netwerk/protocol/about/public/nsIAboutModule.idl @@ -58,6 +58,12 @@ interface nsIAboutModule : nsISupports */ const unsigned long URI_SAFE_FOR_UNTRUSTED_CONTENT = (1 << 0); + /** + * A flag that indicates whether script should be enabled for the + * given about: URI even if it's disabled in general. + */ + const unsigned long ALLOW_SCRIPT = (1 << 1); + /** * A method to get the flags that apply to a given about: URI. The URI * passed in is guaranteed to be one of the URIs that this module diff --git a/mozilla/netwerk/protocol/about/src/nsAboutProtocolHandler.cpp b/mozilla/netwerk/protocol/about/src/nsAboutProtocolHandler.cpp index 104e62f52b2..df01280ca1a 100644 --- a/mozilla/netwerk/protocol/about/src/nsAboutProtocolHandler.cpp +++ b/mozilla/netwerk/protocol/about/src/nsAboutProtocolHandler.cpp @@ -105,7 +105,7 @@ nsAboutProtocolHandler::NewURI(const nsACString &aSpec, PRBool isSafe = PR_FALSE; nsCOMPtr aboutMod; - rv = GetModuleForURI(url, getter_AddRefs(aboutMod)); + rv = NS_GetAboutModule(url, getter_AddRefs(aboutMod)); if (NS_SUCCEEDED(rv)) { // The standard return case PRUint32 flags; @@ -147,7 +147,7 @@ nsAboutProtocolHandler::NewChannel(nsIURI* uri, nsIChannel* *result) // about:what you ask? nsCOMPtr aboutMod; - nsresult rv = GetModuleForURI(uri, getter_AddRefs(aboutMod)); + nsresult rv = NS_GetAboutModule(uri, getter_AddRefs(aboutMod)); if (NS_SUCCEEDED(rv)) { // The standard return case: return aboutMod->NewChannel(uri, result); @@ -172,24 +172,6 @@ nsAboutProtocolHandler::AllowPort(PRInt32 port, const char *scheme, PRBool *_ret return NS_OK; } -//////////////////////////////////////////////////////////////////////////////// -/* static */ -nsresult -nsAboutProtocolHandler::GetModuleForURI(nsIURI* uri, nsIAboutModule** module) -{ - NS_PRECONDITION(uri, "Must have URI"); - - nsresult rv; - nsCAutoString contractID; - rv = NS_GetAboutModuleName(uri, contractID); - if (NS_FAILED(rv)) return rv; - - // look up a handler to deal with "what" - contractID.Insert(NS_LITERAL_CSTRING(NS_ABOUT_MODULE_CONTRACTID_PREFIX), 0); - - return CallGetService(contractID.get(), module); -} - //////////////////////////////////////////////////////////////////////////////// // Safe about protocol handler impl diff --git a/mozilla/netwerk/protocol/about/src/nsAboutProtocolHandler.h b/mozilla/netwerk/protocol/about/src/nsAboutProtocolHandler.h index 80dd4f4640d..ca1a3f8a2e8 100644 --- a/mozilla/netwerk/protocol/about/src/nsAboutProtocolHandler.h +++ b/mozilla/netwerk/protocol/about/src/nsAboutProtocolHandler.h @@ -54,9 +54,6 @@ public: // nsAboutProtocolHandler methods: nsAboutProtocolHandler() {} virtual ~nsAboutProtocolHandler() {} - -protected: - static nsresult GetModuleForURI(nsIURI* uri, nsIAboutModule** module); }; class nsSafeAboutProtocolHandler : public nsIProtocolHandler diff --git a/mozilla/netwerk/protocol/about/src/nsAboutRedirector.cpp b/mozilla/netwerk/protocol/about/src/nsAboutRedirector.cpp index 41363da8d02..31710d32a5f 100644 --- a/mozilla/netwerk/protocol/about/src/nsAboutRedirector.cpp +++ b/mozilla/netwerk/protocol/about/src/nsAboutRedirector.cpp @@ -51,6 +51,9 @@ struct RedirEntry { const char* id; const char* url; PRBool dropChromePrivs; // if PR_TRUE, the page will not have chrome privileges + PRBool allowScripts; // if PR_TRUE, the page will be able to run scripts + // even if script is generally disabled and it + // doesn't have chrome privileges. Use sparingly! }; /* @@ -61,16 +64,17 @@ struct RedirEntry { before adding new map entries with dropChromePrivs == PR_FALSE. */ static RedirEntry kRedirMap[] = { - { "credits", "http://www.mozilla.org/credits/", PR_TRUE }, - { "mozilla", "chrome://global/content/mozilla.xhtml", PR_TRUE }, - { "plugins", "chrome://global/content/plugins.html", PR_FALSE }, - { "config", "chrome://global/content/config.xul", PR_FALSE }, - { "logo", "chrome://global/content/logo.gif", PR_TRUE }, - { "buildconfig", "chrome://global/content/buildconfig.html", PR_TRUE }, - { "license", "chrome://global/content/license.html", PR_TRUE }, - { "licence", "chrome://global/content/license.html", PR_TRUE }, - { "about", "chrome://global/content/aboutAbout.html", PR_FALSE }, - { "neterror", "chrome://global/content/netError.xhtml", PR_TRUE } + { "credits", "http://www.mozilla.org/credits/", PR_TRUE, PR_FALSE }, + { "mozilla", "chrome://global/content/mozilla.xhtml", PR_TRUE, PR_FALSE }, + { "plugins", "chrome://global/content/plugins.html", PR_FALSE, PR_FALSE }, + { "config", "chrome://global/content/config.xul", PR_FALSE, PR_FALSE }, + { "logo", "chrome://global/content/logo.gif", PR_TRUE, PR_FALSE }, + { "buildconfig", "chrome://global/content/buildconfig.html", + PR_TRUE, PR_FALSE }, + { "license", "chrome://global/content/license.html", PR_TRUE, PR_FALSE }, + { "licence", "chrome://global/content/license.html", PR_TRUE, PR_FALSE }, + { "about", "chrome://global/content/aboutAbout.html", PR_FALSE, PR_FALSE }, + { "neterror", "chrome://global/content/netError.xhtml", PR_TRUE, PR_TRUE } }; static const int kRedirTotal = NS_ARRAY_LENGTH(kRedirMap); @@ -145,6 +149,9 @@ nsAboutRedirector::GetURIFlags(nsIURI *aURI, PRUint32 *result) { *result = kRedirMap[i].dropChromePrivs ? nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT : 0; + if (kRedirMap[i].allowScripts) { + *result |= nsIAboutModule::ALLOW_SCRIPT; + } return NS_OK; } } diff --git a/mozilla/xpfe/appshell/src/nsAbout.cpp b/mozilla/xpfe/appshell/src/nsAbout.cpp index f7c18397cb3..e541c70291d 100644 --- a/mozilla/xpfe/appshell/src/nsAbout.cpp +++ b/mozilla/xpfe/appshell/src/nsAbout.cpp @@ -80,7 +80,7 @@ nsAbout::NewChannel(nsIURI *aURI, nsIChannel **result) NS_IMETHODIMP nsAbout::GetURIFlags(nsIURI *aURI, PRUint32 *result) { - *result = 0; + *result = nsIAboutModule::ALLOW_SCRIPT; return NS_OK; }