Bug 840488 - Directly mark compartments whose docshells disable script execution. r=bz

This commit is contained in:
Bobby Holley
2013-11-12 16:43:33 -08:00
parent 035fbf805a
commit fcc9169d4f
7 changed files with 88 additions and 33 deletions

View File

@@ -762,6 +762,7 @@ nsDocShell::nsDocShell():
mUseGlobalHistory(false),
mInPrivateBrowsing(false),
mDeviceSizeIsPageSize(false),
mCanExecuteScripts(false),
mFiredUnloadEvent(false),
mEODForCurrentDocument(false),
mURIResultedInDocument(false),
@@ -2084,6 +2085,7 @@ NS_IMETHODIMP
nsDocShell::SetAllowJavascript(bool aAllowJavascript)
{
mAllowJavascript = aAllowJavascript;
RecomputeCanExecuteScripts();
return NS_OK;
}
@@ -2817,6 +2819,48 @@ nsDocShell::GetParentDocshell()
return docshell.forget().downcast<nsDocShell>();
}
void
nsDocShell::RecomputeCanExecuteScripts()
{
bool old = mCanExecuteScripts;
nsRefPtr<nsDocShell> parent = GetParentDocshell();
// If we have no tree owner, that means that we've been detached from the
// docshell tree (this is distinct from having no parent dochshell, which
// is the case for root docshells). In that case, don't allow script.
if (!mTreeOwner) {
mCanExecuteScripts = false;
// If scripting has been explicitly disabled on our docshell, we're done.
} else if (!mAllowJavascript) {
mCanExecuteScripts = false;
// If we have a parent, inherit.
} else if (parent) {
mCanExecuteScripts = parent->mCanExecuteScripts;
// Otherwise, we're the root of the tree, and we haven't explicitly disabled
// script. Allow.
} else {
mCanExecuteScripts = true;
}
// Inform our active DOM window.
//
// This will pass the outer, which will be in the scope of the active inner.
if (mScriptGlobal && mScriptGlobal->GetGlobalJSObject()) {
xpc::Scriptability& scriptability =
xpc::Scriptability::Get(mScriptGlobal->GetGlobalJSObject());
scriptability.SetDocShellAllowsScript(mCanExecuteScripts);
}
// If our value has changed, our children might be affected. Recompute their
// value as well.
if (old != mCanExecuteScripts) {
nsTObserverArray<nsDocLoader*>::ForwardIterator iter(mChildList);
while (iter.HasMore()) {
static_cast<nsDocShell*>(iter.GetNext())->RecomputeCanExecuteScripts();
}
}
}
nsresult
nsDocShell::SetDocLoaderParent(nsDocLoader * aParent)
{
@@ -2886,6 +2930,10 @@ nsDocShell::SetDocLoaderParent(nsDocLoader * aParent)
nsCOMPtr<nsIURIContentListener> parentURIListener(do_GetInterface(parent));
if (parentURIListener)
mContentListener->SetParentContentListener(parentURIListener);
// Our parent has changed. Recompute scriptability.
RecomputeCanExecuteScripts();
return NS_OK;
}
@@ -3440,6 +3488,16 @@ nsDocShell::SetTreeOwner(nsIDocShellTreeOwner * aTreeOwner)
child->SetTreeOwner(aTreeOwner);
}
// Our tree owner has changed. Recompute scriptability.
//
// Note that this is near-redundant with the recomputation in
// SetDocLoaderParent(), but not so for the root DocShell, where the call to
// SetTreeOwner() happens after the initial AddDocLoaderAsChildOfRoot(),
// and we never set another parent. Given that this is neither expensive nor
// performance-critical, let's be safe and unconditionally recompute this
// state whenever dependent state changes.
RecomputeCanExecuteScripts();
return NS_OK;
}
@@ -12651,20 +12709,7 @@ unsigned long nsDocShell::gNumberOfDocShells = 0;
NS_IMETHODIMP
nsDocShell::GetCanExecuteScripts(bool *aResult)
{
NS_ENSURE_ARG_POINTER(aResult);
*aResult = false; // disallow by default
nsRefPtr<nsDocShell> docshell = this;
do {
nsresult rv = docshell->GetAllowJavascript(aResult);
if (NS_FAILED(rv)) return rv;
if (!*aResult) {
return NS_OK;
}
docshell = docshell->GetParentDocshell();
} while (docshell);
*aResult = mCanExecuteScripts;
return NS_OK;
}