Bug 840488 - Refactor Gecko to provide a more direct API to ask whether script is allowed for a given global. r=bz

This commit is contained in:
Bobby Holley 2013-11-12 16:43:31 -08:00
parent 9f988a30ca
commit d071bd541c
8 changed files with 40 additions and 71 deletions

View File

@ -10,7 +10,7 @@ interface nsIURI;
interface nsIChannel;
interface nsIDocShell;
[scriptable, uuid(d6475e53-9ece-4dc0-940c-095ac3d85363)]
[scriptable, uuid(374ab3e6-d827-479f-b966-eeed90e94788)]
interface nsIScriptSecurityManager : nsIXPCSecurityManager
{
///////////////// Security Checks //////////////////
@ -116,11 +116,9 @@ interface nsIScriptSecurityManager : nsIXPCSecurityManager
in voidPtr targetObj);
/**
* Return true if content from the given principal is allowed to
* execute scripts.
* Return true if scripts may be executed in the scope of the given global.
*/
[noscript] boolean canExecuteScripts(in JSContextPtr cx,
in nsIPrincipal principal);
[noscript,notxpcom] boolean scriptAllowed(in JSObjectPtr aGlobal);
///////////////// Principals ///////////////////////
/**

View File

@ -63,6 +63,7 @@
#include "mozilla/StaticPtr.h"
#include "nsContentUtils.h"
#include "nsCxPusher.h"
#include "nsJSUtils.h"
// This should be probably defined on some other place... but I couldn't find it
#define WEBAPPS_PERM_NAME "webapps-manage"
@ -1649,14 +1650,6 @@ nsScriptSecurityManager::CheckFunctionAccess(JSContext *aCx, void *aFunObj,
return rv;
}
NS_IMETHODIMP
nsScriptSecurityManager::CanExecuteScripts(JSContext* cx,
nsIPrincipal *aPrincipal,
bool *result)
{
return CanExecuteScripts(cx, aPrincipal, false, result);
}
nsresult
nsScriptSecurityManager::CanExecuteScripts(JSContext* cx,
nsIPrincipal *aPrincipal,
@ -1770,6 +1763,23 @@ nsScriptSecurityManager::CanExecuteScripts(JSContext* cx,
return NS_OK;
}
NS_IMETHODIMP_(bool)
nsScriptSecurityManager::ScriptAllowed(JSObject *aGlobal)
{
MOZ_ASSERT(aGlobal);
MOZ_ASSERT(JS_IsGlobalObject(aGlobal) || js::IsOuterObject(aGlobal));
AutoJSContext cx_;
JS::RootedObject global(cx_, js::UncheckedUnwrap(aGlobal, /* stopAtOuter = */ false));
nsCOMPtr<nsIScriptContext> scx = nsJSUtils::GetStaticScriptContext(global);
AutoPushJSContext cx(scx ? scx->GetNativeContext() : GetSafeJSContext());
bool result = false;
nsresult rv = CanExecuteScripts(cx, doGetObjectPrincipal(global),
/* aAllowIfNoScriptContext = */ false,
&result);
return NS_SUCCEEDED(rv) && result;
}
///////////////// Principals ///////////////////////
NS_IMETHODIMP
nsScriptSecurityManager::GetSubjectPrincipal(nsIPrincipal **aSubjectPrincipal)

View File

@ -7206,19 +7206,10 @@ nsDocument::IsScriptEnabled()
nsCOMPtr<nsIScriptSecurityManager> sm(do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID));
NS_ENSURE_TRUE(sm, false);
nsCOMPtr<nsIScriptGlobalObject> globalObject = do_QueryInterface(GetWindow());
NS_ENSURE_TRUE(globalObject, false);
nsCOMPtr<nsIScriptGlobalObject> globalObject = do_QueryInterface(GetInnerWindow());
NS_ENSURE_TRUE(globalObject && globalObject->GetGlobalJSObject(), false);
nsIScriptContext *scriptContext = globalObject->GetContext();
NS_ENSURE_TRUE(scriptContext, false);
AutoPushJSContext cx(scriptContext->GetNativeContext());
NS_ENSURE_TRUE(cx, false);
bool enabled;
nsresult rv = sm->CanExecuteScripts(cx, NodePrincipal(), &enabled);
NS_ENSURE_SUCCESS(rv, false);
return enabled;
return sm->ScriptAllowed(globalObject->GetGlobalJSObject());
}
nsRadioGroupStruct*

View File

@ -706,24 +706,17 @@ IsScriptEnabled(nsIDocument *aDoc, nsIDocShell *aContainer)
NS_ENSURE_TRUE(aDoc && aContainer, true);
nsCOMPtr<nsIScriptGlobalObject> globalObject =
do_QueryInterface(aDoc->GetWindow());
do_QueryInterface(aDoc->GetInnerWindow());
// Getting context is tricky if the document hasn't had its
// GlobalObject set yet
if (!globalObject) {
globalObject = aContainer->GetScriptGlobalObject();
NS_ENSURE_TRUE(globalObject, true);
}
nsIScriptContext *scriptContext = globalObject->GetContext();
NS_ENSURE_TRUE(scriptContext, true);
JSContext *cx = scriptContext->GetNativeContext();
NS_ENSURE_TRUE(cx, true);
bool enabled = true;
nsContentUtils::GetSecurityManager()->
CanExecuteScripts(cx, aDoc->NodePrincipal(), &enabled);
return enabled;
NS_ENSURE_TRUE(globalObject && globalObject->GetGlobalJSObject(), true);
return nsContentUtils::GetSecurityManager()->
ScriptAllowed(globalObject->GetGlobalJSObject());
}
nsresult

View File

@ -1080,24 +1080,12 @@ nsXBLBinding::AllowScripts()
return false;
}
nsCOMPtr<nsIScriptGlobalObject> global = do_QueryInterface(doc->GetWindow());
if (!global) {
nsCOMPtr<nsIScriptGlobalObject> global = do_QueryInterface(doc->GetInnerWindow());
if (!global || !global->GetGlobalJSObject()) {
return false;
}
nsCOMPtr<nsIScriptContext> context = global->GetContext();
if (!context) {
return false;
}
AutoPushJSContext cx(context->GetNativeContext());
nsCOMPtr<nsIDocument> ourDocument =
mPrototypeBinding->XBLDocumentInfo()->GetDocument();
bool canExecute;
nsresult rv =
mgr->CanExecuteScripts(cx, ourDocument->NodePrincipal(), &canExecute);
return NS_SUCCEEDED(rv) && canExecute;
return mgr->ScriptAllowed(global->GetGlobalJSObject());
}
nsXBLBinding*

View File

@ -241,15 +241,14 @@ nsJSUtils::EvaluateString(JSContext* aCx,
JS::ExposeObjectToActiveJS(aScopeObject);
nsAutoMicroTask mt;
nsresult rv = NS_OK;
JSPrincipals* p = JS_GetCompartmentPrincipals(js::GetObjectCompartment(aScopeObject));
aCompileOptions.setPrincipals(p);
bool ok = false;
nsresult rv = nsContentUtils::GetSecurityManager()->
CanExecuteScripts(aCx, nsJSPrincipals::get(p), &ok);
NS_ENSURE_SUCCESS(rv, rv);
NS_ENSURE_TRUE(ok, NS_OK);
nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager();
NS_ENSURE_TRUE(ssm->ScriptAllowed(js::GetGlobalForObjectCrossCompartment(aScopeObject)), NS_OK);
mozilla::Maybe<AutoDontReportUncaught> dontReport;
if (!aEvaluateOptions.reportUncaught) {

View File

@ -240,6 +240,7 @@ nsresult nsJSThunk::EvaluateScript(nsIChannel *aChannel,
AutoPushJSContext cx(scriptContext->GetNativeContext());
JS::Rooted<JSObject*> globalJSObject(cx, innerGlobal->GetGlobalJSObject());
NS_ENSURE_TRUE(globalJSObject, NS_ERROR_UNEXPECTED);
if (!useSandbox) {
//-- Don't outside a sandbox unless the script principal subsumes the
@ -264,13 +265,7 @@ nsresult nsJSThunk::EvaluateScript(nsIChannel *aChannel,
// First check to make sure it's OK to evaluate this script to
// start with. For example, script could be disabled.
bool ok;
rv = securityManager->CanExecuteScripts(cx, principal, &ok);
if (NS_FAILED(rv)) {
return rv;
}
if (!ok) {
if (!securityManager->ScriptAllowed(globalJSObject)) {
// Treat this as returning undefined from the script. That's what
// nsJSContext does.
return NS_ERROR_DOM_RETVAL_UNDEFINED;

View File

@ -648,21 +648,16 @@ nsHtml5TreeOpExecutor::IsScriptEnabled()
{
if (!mDocument || !mDocShell)
return true;
nsCOMPtr<nsIScriptGlobalObject> globalObject = do_QueryInterface(mDocument->GetWindow());
nsCOMPtr<nsIScriptGlobalObject> globalObject = do_QueryInterface(mDocument->GetInnerWindow());
// Getting context is tricky if the document hasn't had its
// GlobalObject set yet
if (!globalObject) {
globalObject = mDocShell->GetScriptGlobalObject();
NS_ENSURE_TRUE(globalObject, true);
}
nsIScriptContext *scriptContext = globalObject->GetContext();
NS_ENSURE_TRUE(scriptContext, true);
JSContext* cx = scriptContext->GetNativeContext();
NS_ENSURE_TRUE(cx, true);
bool enabled = true;
nsContentUtils::GetSecurityManager()->
CanExecuteScripts(cx, mDocument->NodePrincipal(), &enabled);
return enabled;
NS_ENSURE_TRUE(globalObject && globalObject->GetGlobalJSObject(), true);
return nsContentUtils::GetSecurityManager()->
ScriptAllowed(globalObject->GetGlobalJSObject());
}
void