Bug 785310 - HTML5 sandboxed iframe should not be able to perform top navigation when scripts are allowed. r=bholley, r=smaug

This commit is contained in:
Bob Owen 2014-01-13 07:58:16 +00:00
parent aabad2abb4
commit d8885ccdf2
9 changed files with 133 additions and 86 deletions

View File

@ -1323,6 +1323,7 @@ nsDocShell::LoadURI(nsIURI * aURI,
nsCOMPtr<nsISHEntry> shEntry; nsCOMPtr<nsISHEntry> shEntry;
nsXPIDLString target; nsXPIDLString target;
nsAutoString srcdoc; nsAutoString srcdoc;
nsCOMPtr<nsIDocShell> sourceDocShell;
uint32_t loadType = MAKE_LOAD_TYPE(LOAD_NORMAL, aLoadFlags); uint32_t loadType = MAKE_LOAD_TYPE(LOAD_NORMAL, aLoadFlags);
@ -1352,6 +1353,7 @@ nsDocShell::LoadURI(nsIURI * aURI,
aLoadInfo->GetSendReferrer(&sendReferrer); aLoadInfo->GetSendReferrer(&sendReferrer);
aLoadInfo->GetIsSrcdocLoad(&isSrcdoc); aLoadInfo->GetIsSrcdocLoad(&isSrcdoc);
aLoadInfo->GetSrcdocData(srcdoc); aLoadInfo->GetSrcdocData(srcdoc);
aLoadInfo->GetSourceDocShell(getter_AddRefs(sourceDocShell));
} }
#if defined(PR_LOGGING) && defined(DEBUG) #if defined(PR_LOGGING) && defined(DEBUG)
@ -1597,6 +1599,7 @@ nsDocShell::LoadURI(nsIURI * aURI,
nullptr, // No SHEntry nullptr, // No SHEntry
aFirstParty, aFirstParty,
srcdoc, srcdoc,
sourceDocShell,
nullptr, // No nsIDocShell nullptr, // No nsIDocShell
nullptr); // No nsIRequest nullptr); // No nsIRequest
} }
@ -3303,11 +3306,7 @@ nsDocShell::FindItemWithName(const char16_t * aName,
// DoFindItemWithName only returns active items and we don't check if // DoFindItemWithName only returns active items and we don't check if
// the item is active for the special cases. // the item is active for the special cases.
if (foundItem) { if (foundItem) {
if (IsSandboxedFrom(foundItem, aOriginalRequestor)) { foundItem.swap(*_retval);
return NS_ERROR_DOM_INVALID_ACCESS_ERR;
} else {
foundItem.swap(*_retval);
}
} }
return NS_OK; return NS_OK;
} }
@ -3380,35 +3379,38 @@ nsDocShell::DoFindItemWithName(const char16_t* aName,
return NS_OK; return NS_OK;
} }
/* static */
bool bool
nsDocShell::IsSandboxedFrom(nsIDocShellTreeItem* aTargetItem, nsDocShell::IsSandboxedFrom(nsIDocShell* aTargetDocShell)
nsIDocShellTreeItem* aAccessingItem)
{ {
// aAccessingItem cannot be sandboxed from itself. // If no target then not sandboxed.
if (SameCOMIdentity(aTargetItem, aAccessingItem)) { if (!aTargetDocShell) {
return false;
}
// We cannot be sandboxed from ourselves.
if (aTargetDocShell == this) {
return false; return false;
} }
uint32_t sandboxFlags = 0; uint32_t sandboxFlags = 0;
nsCOMPtr<nsIDocument> doc = do_GetInterface(aAccessingItem); nsCOMPtr<nsIDocument> doc = mContentViewer->GetDocument();
if (doc) { if (doc) {
sandboxFlags = doc->GetSandboxFlags(); sandboxFlags = doc->GetSandboxFlags();
} }
// If no flags, aAccessingItem is not sandboxed at all. // If no flags, we are not sandboxed at all.
if (!sandboxFlags) { if (!sandboxFlags) {
return false; return false;
} }
// If aTargetItem has an ancestor, it is not top level. // If aTargetDocShell has an ancestor, it is not top level.
nsCOMPtr<nsIDocShellTreeItem> ancestorOfTarget; nsCOMPtr<nsIDocShellTreeItem> ancestorOfTarget;
aTargetItem->GetSameTypeParent(getter_AddRefs(ancestorOfTarget)); aTargetDocShell->GetSameTypeParent(getter_AddRefs(ancestorOfTarget));
if (ancestorOfTarget) { if (ancestorOfTarget) {
do { do {
// aAccessingItem is not sandboxed if it is an ancestor of target. // We are not sandboxed if we are an ancestor of target.
if (SameCOMIdentity(aAccessingItem, ancestorOfTarget)) { if (ancestorOfTarget == this) {
return false; return false;
} }
nsCOMPtr<nsIDocShellTreeItem> tempTreeItem; nsCOMPtr<nsIDocShellTreeItem> tempTreeItem;
@ -3416,31 +3418,30 @@ nsDocShell::IsSandboxedFrom(nsIDocShellTreeItem* aTargetItem,
tempTreeItem.swap(ancestorOfTarget); tempTreeItem.swap(ancestorOfTarget);
} while (ancestorOfTarget); } while (ancestorOfTarget);
// Otherwise, aAccessingItem is sandboxed from aTargetItem. // Otherwise, we are sandboxed from aTargetDocShell.
return true; return true;
} }
// aTargetItem is top level, is aAccessingItem the "one permitted sandboxed // aTargetDocShell is top level, are we the "one permitted sandboxed
// navigator", i.e. did aAccessingItem open aTargetItem? // navigator", i.e. did we open aTargetDocShell?
nsCOMPtr<nsIDocShell> targetDocShell = do_QueryInterface(aTargetItem);
nsCOMPtr<nsIDocShell> permittedNavigator; nsCOMPtr<nsIDocShell> permittedNavigator;
targetDocShell-> aTargetDocShell->
GetOnePermittedSandboxedNavigator(getter_AddRefs(permittedNavigator)); GetOnePermittedSandboxedNavigator(getter_AddRefs(permittedNavigator));
if (SameCOMIdentity(aAccessingItem, permittedNavigator)) { if (permittedNavigator == this) {
return false; return false;
} }
// If SANDBOXED_TOPLEVEL_NAVIGATION flag is not on, aAccessingItem is // If SANDBOXED_TOPLEVEL_NAVIGATION flag is not on, we are not sandboxed
// not sandboxed from its top. // from our top.
if (!(sandboxFlags & SANDBOXED_TOPLEVEL_NAVIGATION)) { if (!(sandboxFlags & SANDBOXED_TOPLEVEL_NAVIGATION)) {
nsCOMPtr<nsIDocShellTreeItem> rootTreeItem; nsCOMPtr<nsIDocShellTreeItem> rootTreeItem;
aAccessingItem->GetSameTypeRootTreeItem(getter_AddRefs(rootTreeItem)); GetSameTypeRootTreeItem(getter_AddRefs(rootTreeItem));
if (SameCOMIdentity(aTargetItem, rootTreeItem)) { if (SameCOMIdentity(aTargetDocShell, rootTreeItem)) {
return false; return false;
} }
} }
// Otherwise, aAccessingItem is sandboxed from aTargetItem. // Otherwise, we are sandboxed from aTargetDocShell.
return true; return true;
} }
@ -4793,7 +4794,7 @@ nsDocShell::LoadErrorPage(nsIURI *aURI, const char16_t *aURL,
return InternalLoad(errorPageURI, nullptr, nullptr, return InternalLoad(errorPageURI, nullptr, nullptr,
INTERNAL_LOAD_FLAGS_INHERIT_OWNER, nullptr, nullptr, INTERNAL_LOAD_FLAGS_INHERIT_OWNER, nullptr, nullptr,
NullString(), nullptr, nullptr, LOAD_ERROR_PAGE, NullString(), nullptr, nullptr, LOAD_ERROR_PAGE,
nullptr, true, NullString(), nullptr,nullptr); nullptr, true, NullString(), this, nullptr, nullptr);
} }
@ -4861,6 +4862,7 @@ nsDocShell::Reload(uint32_t aReloadFlags)
nullptr, // No SHEntry nullptr, // No SHEntry
true, true,
srcdoc, // srcdoc argument for iframe srcdoc, // srcdoc argument for iframe
this, // For reloads we are the source
nullptr, // No nsIDocShell nullptr, // No nsIDocShell
nullptr); // No nsIRequest nullptr); // No nsIRequest
} }
@ -8636,7 +8638,7 @@ public:
const char* aTypeHint, nsIInputStream * aPostData, const char* aTypeHint, nsIInputStream * aPostData,
nsIInputStream * aHeadersData, uint32_t aLoadType, nsIInputStream * aHeadersData, uint32_t aLoadType,
nsISHEntry * aSHEntry, bool aFirstParty, nsISHEntry * aSHEntry, bool aFirstParty,
const nsAString &aSrcdoc) : const nsAString &aSrcdoc, nsIDocShell* aSourceDocShell) :
mSrcdoc(aSrcdoc), mSrcdoc(aSrcdoc),
mDocShell(aDocShell), mDocShell(aDocShell),
mURI(aURI), mURI(aURI),
@ -8647,7 +8649,8 @@ public:
mSHEntry(aSHEntry), mSHEntry(aSHEntry),
mFlags(aFlags), mFlags(aFlags),
mLoadType(aLoadType), mLoadType(aLoadType),
mFirstParty(aFirstParty) mFirstParty(aFirstParty),
mSourceDocShell(aSourceDocShell)
{ {
// Make sure to keep null things null as needed // Make sure to keep null things null as needed
if (aTypeHint) { if (aTypeHint) {
@ -8660,7 +8663,7 @@ public:
nullptr, mTypeHint.get(), nullptr, mTypeHint.get(),
NullString(), mPostData, mHeadersData, NullString(), mPostData, mHeadersData,
mLoadType, mSHEntry, mFirstParty, mLoadType, mSHEntry, mFirstParty,
mSrcdoc, nullptr, nullptr); mSrcdoc, mSourceDocShell, nullptr, nullptr);
} }
private: private:
@ -8680,6 +8683,7 @@ private:
uint32_t mFlags; uint32_t mFlags;
uint32_t mLoadType; uint32_t mLoadType;
bool mFirstParty; bool mFirstParty;
nsCOMPtr<nsIDocShell> mSourceDocShell;
}; };
/** /**
@ -8713,6 +8717,7 @@ nsDocShell::InternalLoad(nsIURI * aURI,
nsISHEntry * aSHEntry, nsISHEntry * aSHEntry,
bool aFirstParty, bool aFirstParty,
const nsAString &aSrcdoc, const nsAString &aSrcdoc,
nsIDocShell* aSourceDocShell,
nsIDocShell** aDocShell, nsIDocShell** aDocShell,
nsIRequest** aRequest) nsIRequest** aRequest)
{ {
@ -8776,10 +8781,9 @@ nsDocShell::InternalLoad(nsIURI * aURI,
if (aWindowTarget && *aWindowTarget) { if (aWindowTarget && *aWindowTarget) {
// Locate the target DocShell. // Locate the target DocShell.
nsCOMPtr<nsIDocShellTreeItem> targetItem; nsCOMPtr<nsIDocShellTreeItem> targetItem;
if (FindItemWithName(aWindowTarget, nullptr, this, rv = FindItemWithName(aWindowTarget, nullptr, this,
getter_AddRefs(targetItem)) == NS_ERROR_DOM_INVALID_ACCESS_ERR) { getter_AddRefs(targetItem));
return NS_ERROR_DOM_INVALID_ACCESS_ERR; NS_ENSURE_SUCCESS(rv, rv);
}
targetDocShell = do_QueryInterface(targetItem); targetDocShell = do_QueryInterface(targetItem);
// If the targetDocShell doesn't exist, then this is a new docShell // If the targetDocShell doesn't exist, then this is a new docShell
@ -8968,6 +8972,7 @@ nsDocShell::InternalLoad(nsIURI * aURI,
aSHEntry, aSHEntry,
aFirstParty, aFirstParty,
aSrcdoc, aSrcdoc,
aSourceDocShell,
aDocShell, aDocShell,
aRequest); aRequest);
if (rv == NS_ERROR_NO_CONTENT) { if (rv == NS_ERROR_NO_CONTENT) {
@ -9022,17 +9027,6 @@ nsDocShell::InternalLoad(nsIURI * aURI,
return rv; return rv;
} }
// If this docshell is owned by a frameloader, make sure to cancel
// possible frameloader initialization before loading a new page.
nsCOMPtr<nsIDocShellTreeItem> parent;
GetParent(getter_AddRefs(parent));
if (parent) {
nsCOMPtr<nsIDocument> doc = do_GetInterface(parent);
if (doc) {
doc->TryCancelFrameLoaderInitialization(this);
}
}
if (mFiredUnloadEvent) { if (mFiredUnloadEvent) {
if (IsOKToLoadURI(aURI)) { if (IsOKToLoadURI(aURI)) {
NS_PRECONDITION(!aWindowTarget || !*aWindowTarget, NS_PRECONDITION(!aWindowTarget || !*aWindowTarget,
@ -9049,7 +9043,8 @@ nsDocShell::InternalLoad(nsIURI * aURI,
nsCOMPtr<nsIRunnable> ev = nsCOMPtr<nsIRunnable> ev =
new InternalLoadEvent(this, aURI, aReferrer, aOwner, aFlags, new InternalLoadEvent(this, aURI, aReferrer, aOwner, aFlags,
aTypeHint, aPostData, aHeadersData, aTypeHint, aPostData, aHeadersData,
aLoadType, aSHEntry, aFirstParty, aSrcdoc); aLoadType, aSHEntry, aFirstParty, aSrcdoc,
aSourceDocShell);
return NS_DispatchToCurrentThread(ev); return NS_DispatchToCurrentThread(ev);
} }
@ -9057,6 +9052,23 @@ nsDocShell::InternalLoad(nsIURI * aURI,
return NS_OK; return NS_OK;
} }
// If a source docshell has been passed, check to see if we are sandboxed
// from it as the result of an iframe or CSP sandbox.
if (aSourceDocShell && aSourceDocShell->IsSandboxedFrom(this)) {
return NS_ERROR_DOM_INVALID_ACCESS_ERR;
}
// If this docshell is owned by a frameloader, make sure to cancel
// possible frameloader initialization before loading a new page.
nsCOMPtr<nsIDocShellTreeItem> parent;
GetParent(getter_AddRefs(parent));
if (parent) {
nsCOMPtr<nsIDocument> doc = do_GetInterface(parent);
if (doc) {
doc->TryCancelFrameLoaderInitialization(this);
}
}
// Before going any further vet loads initiated by external programs. // Before going any further vet loads initiated by external programs.
if (aLoadType == LOAD_NORMAL_EXTERNAL) { if (aLoadType == LOAD_NORMAL_EXTERNAL) {
// Disallow external chrome: loads targetted at content windows // Disallow external chrome: loads targetted at content windows
@ -11067,6 +11079,10 @@ nsDocShell::LoadHistoryEntry(nsISHEntry * aEntry, uint32_t aLoadType)
srcdoc = NullString(); srcdoc = NullString();
} }
// Passing nullptr as aSourceDocShell gives the same behaviour as before
// aSourceDocShell was introduced. According to spec we should be passing
// the source browsing context that was used when the history entry was
// first created. bug 947716 has been created to address this issue.
rv = InternalLoad(uri, rv = InternalLoad(uri,
referrerURI, referrerURI,
owner, owner,
@ -11080,6 +11096,7 @@ nsDocShell::LoadHistoryEntry(nsISHEntry * aEntry, uint32_t aLoadType)
aEntry, // SHEntry aEntry, // SHEntry
true, true,
srcdoc, srcdoc,
nullptr, // Source docshell, see comment above
nullptr, // No nsIDocShell nullptr, // No nsIDocShell
nullptr); // No nsIRequest nullptr); // No nsIRequest
return rv; return rv;
@ -12494,6 +12511,7 @@ nsDocShell::OnLinkClickSync(nsIContent *aContent,
nullptr, // No SHEntry nullptr, // No SHEntry
true, // first party site true, // first party site
NullString(), // No srcdoc NullString(), // No srcdoc
this, // We are the source
aDocShell, // DocShell out-param aDocShell, // DocShell out-param
aRequest); // Request out-param aRequest); // Request out-param
if (NS_SUCCEEDED(rv)) { if (NS_SUCCEEDED(rv)) {

View File

@ -889,10 +889,6 @@ private:
nsIDocShellTreeItem* aOriginalRequestor, nsIDocShellTreeItem* aOriginalRequestor,
nsIDocShellTreeItem** _retval); nsIDocShellTreeItem** _retval);
// Check whether accessing item is sandboxed from the target item.
static bool IsSandboxedFrom(nsIDocShellTreeItem* aTargetItem,
nsIDocShellTreeItem* aAccessingItem);
#ifdef DEBUG #ifdef DEBUG
// We're counting the number of |nsDocShells| to help find leaks // We're counting the number of |nsDocShells| to help find leaks
static unsigned long gNumberOfDocShells; static unsigned long gNumberOfDocShells;

View File

@ -9,6 +9,7 @@
#include "nsISHEntry.h" #include "nsISHEntry.h"
#include "nsIInputStream.h" #include "nsIInputStream.h"
#include "nsIURI.h" #include "nsIURI.h"
#include "nsIDocShell.h"
//***************************************************************************** //*****************************************************************************
//*** nsDocShellLoadInfo: Object Management //*** nsDocShellLoadInfo: Object Management
@ -210,6 +211,19 @@ NS_IMETHODIMP nsDocShellLoadInfo::SetSrcdocData(const nsAString &aSrcdocData)
return NS_OK; return NS_OK;
} }
NS_IMETHODIMP nsDocShellLoadInfo::GetSourceDocShell(nsIDocShell** aSourceDocShell)
{
MOZ_ASSERT(aSourceDocShell);
nsCOMPtr<nsIDocShell> result = mSourceDocShell;
result.forget(aSourceDocShell);
return NS_OK;
}
NS_IMETHODIMP nsDocShellLoadInfo::SetSourceDocShell(nsIDocShell* aSourceDocShell)
{
mSourceDocShell = aSourceDocShell;
return NS_OK;
}
//***************************************************************************** //*****************************************************************************
// nsDocShellLoadInfo: Helpers // nsDocShellLoadInfo: Helpers

View File

@ -18,6 +18,7 @@
class nsIInputStream; class nsIInputStream;
class nsISHEntry; class nsISHEntry;
class nsIURI; class nsIURI;
class nsIDocShell;
class nsDocShellLoadInfo : public nsIDocShellLoadInfo class nsDocShellLoadInfo : public nsIDocShellLoadInfo
{ {
@ -43,6 +44,7 @@ protected:
nsCOMPtr<nsIInputStream> mHeadersStream; nsCOMPtr<nsIInputStream> mHeadersStream;
bool mIsSrcdocLoad; bool mIsSrcdocLoad;
nsString mSrcdocData; nsString mSrcdocData;
nsCOMPtr<nsIDocShell> mSourceDocShell;
}; };
#endif /* nsDocShellLoadInfo_h__ */ #endif /* nsDocShellLoadInfo_h__ */

View File

@ -44,7 +44,7 @@ interface nsIReflowObserver;
typedef unsigned long nsLoadFlags; typedef unsigned long nsLoadFlags;
[scriptable, builtinclass, uuid(e3ea830d-2614-4aeb-9ec3-b8f744b03b80)] [scriptable, builtinclass, uuid(24732b66-e37e-444e-96a2-8b8d1fa292fc)]
interface nsIDocShell : nsIDocShellTreeItem interface nsIDocShell : nsIDocShellTreeItem
{ {
/** /**
@ -138,6 +138,7 @@ interface nsIDocShell : nsIDocShellTreeItem
* @param aSrcdoc When INTERNAL_LOAD_FLAGS_IS_SRCDOC is set, the * @param aSrcdoc When INTERNAL_LOAD_FLAGS_IS_SRCDOC is set, the
* contents of this parameter will be loaded instead * contents of this parameter will be loaded instead
* of aURI. * of aURI.
* @param aSourceDocShell - The source browsing context for the navigation.
*/ */
[noscript]void internalLoad(in nsIURI aURI, [noscript]void internalLoad(in nsIURI aURI,
in nsIURI aReferrer, in nsIURI aReferrer,
@ -152,6 +153,7 @@ interface nsIDocShell : nsIDocShellTreeItem
in nsISHEntry aSHEntry, in nsISHEntry aSHEntry,
in boolean firstParty, in boolean firstParty,
in AString aSrcdoc, in AString aSrcdoc,
in nsIDocShell aSourceDocShell,
out nsIDocShell aDocShell, out nsIDocShell aDocShell,
out nsIRequest aRequest); out nsIRequest aRequest);
@ -785,6 +787,12 @@ interface nsIDocShell : nsIDocShellTreeItem
*/ */
attribute nsIDocShell onePermittedSandboxedNavigator; attribute nsIDocShell onePermittedSandboxedNavigator;
/**
* Returns true if we are sandboxed from aTargetDocShell.
* aTargetDocShell - the browsing context we are attempting to navigate.
*/
[noscript,notxpcom,nostdcall] bool isSandboxedFrom(in nsIDocShell aTargetDocShell);
/** /**
* This member variable determines whether a document has Mixed Active Content that * This member variable determines whether a document has Mixed Active Content that
* was initially blocked from loading, but the user has choosen to override the * was initially blocked from loading, but the user has choosen to override the

View File

@ -14,10 +14,11 @@
interface nsIURI; interface nsIURI;
interface nsIInputStream; interface nsIInputStream;
interface nsISHEntry; interface nsISHEntry;
interface nsIDocShell;
typedef long nsDocShellInfoLoadType; typedef long nsDocShellInfoLoadType;
[scriptable, uuid(5df91211-37db-47e9-8f83-2d5b0cb2eb9e)] [scriptable, uuid(c6b15de3-2f4f-4e80-bb20-95f43b5598c7)]
interface nsIDocShellLoadInfo : nsISupports interface nsIDocShellLoadInfo : nsISupports
{ {
/** This is the referrer for the load. */ /** This is the referrer for the load. */
@ -95,4 +96,6 @@ interface nsIDocShellLoadInfo : nsISupports
*/ */
attribute AString srcdocData; attribute AString srcdocData;
/** When set, this is the Source Browsing Context for the navigation. */
attribute nsIDocShell sourceDocShell;
}; };

View File

@ -237,6 +237,13 @@ nsLocation::SetURI(nsIURI* aURI, bool aReplace)
loadInfo->SetLoadType(nsIDocShellLoadInfo::loadStopContent); loadInfo->SetLoadType(nsIDocShellLoadInfo::loadStopContent);
} }
// Get the incumbent script's browsing context to set as source.
nsCOMPtr<nsPIDOMWindow> sourceWindow =
do_QueryInterface(mozilla::dom::GetIncumbentGlobal());
if (sourceWindow) {
loadInfo->SetSourceDocShell(sourceWindow->GetDocShell());
}
return docShell->LoadURI(aURI, loadInfo, return docShell->LoadURI(aURI, loadInfo,
nsIWebNavigation::LOAD_FLAGS_NONE, true); nsIWebNavigation::LOAD_FLAGS_NONE, true);
} }

View File

@ -474,13 +474,24 @@ nsWindowWatcher::OpenWindowInternal(nsIDOMWindow *aParent,
} }
// try to find an extant window with the given name // try to find an extant window with the given name
nsCOMPtr<nsIDOMWindow> foundWindow; nsCOMPtr<nsIDOMWindow> foundWindow = SafeGetWindowByName(name, aParent);
if (SafeGetWindowByName(name, aParent, getter_AddRefs(foundWindow)) ==
NS_ERROR_DOM_INVALID_ACCESS_ERR) {
return NS_ERROR_DOM_INVALID_ACCESS_ERR;
}
GetWindowTreeItem(foundWindow, getter_AddRefs(newDocShellItem)); GetWindowTreeItem(foundWindow, getter_AddRefs(newDocShellItem));
// Do sandbox checks here, instead of waiting until nsIDocShell::LoadURI.
// The state of the window can change before this call and if we are blocked
// because of sandboxing, we wouldn't want that to happen.
nsCOMPtr<nsPIDOMWindow> parentWindow = do_QueryInterface(aParent);
nsCOMPtr<nsIDocShell> parentDocShell;
if (parentWindow) {
parentDocShell = parentWindow->GetDocShell();
if (parentDocShell) {
nsCOMPtr<nsIDocShell> foundDocShell = do_QueryInterface(newDocShellItem);
if (parentDocShell->IsSandboxedFrom(foundDocShell)) {
return NS_ERROR_DOM_INVALID_ACCESS_ERR;
}
}
}
// no extant window? make a new one. // no extant window? make a new one.
// If no parent, consider it chrome. // If no parent, consider it chrome.
@ -671,9 +682,9 @@ nsWindowWatcher::OpenWindowInternal(nsIDOMWindow *aParent,
bool popupConditions = false; bool popupConditions = false;
// is the parent under popup conditions? // is the parent under popup conditions?
nsCOMPtr<nsPIDOMWindow> piWindow(do_QueryInterface(aParent)); if (parentWindow) {
if (piWindow) popupConditions = parentWindow->IsLoadingOrRunningTimeout();
popupConditions = piWindow->IsLoadingOrRunningTimeout(); }
// chrome is always allowed, so clear the flag if the opener is chrome // chrome is always allowed, so clear the flag if the opener is chrome
if (popupConditions) { if (popupConditions) {
@ -722,9 +733,9 @@ nsWindowWatcher::OpenWindowInternal(nsIDOMWindow *aParent,
// The flags can only be non-zero for new windows. // The flags can only be non-zero for new windows.
if (activeDocsSandboxFlags != 0) { if (activeDocsSandboxFlags != 0) {
newDocShell->SetSandboxFlags(activeDocsSandboxFlags); newDocShell->SetSandboxFlags(activeDocsSandboxFlags);
nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(aParent); if (parentWindow) {
if (window) { newDocShell->
newDocShell->SetOnePermittedSandboxedNavigator(window->GetDocShell()); SetOnePermittedSandboxedNavigator(parentWindow->GetDocShell());
} }
} }
@ -908,11 +919,6 @@ nsWindowWatcher::OpenWindowInternal(nsIDOMWindow *aParent,
} }
// Copy the current session storage for the current domain. // Copy the current session storage for the current domain.
nsCOMPtr<nsPIDOMWindow> piWindow = do_QueryInterface(aParent);
nsIDocShell* parentDocShell = nullptr;
if (piWindow)
parentDocShell = piWindow->GetDocShell();
if (subjectPrincipal && parentDocShell) { if (subjectPrincipal && parentDocShell) {
nsCOMPtr<nsIDOMStorageManager> parentStorageManager = do_QueryInterface(parentDocShell); nsCOMPtr<nsIDOMStorageManager> parentStorageManager = do_QueryInterface(parentDocShell);
nsCOMPtr<nsIDOMStorageManager> newStorageManager = do_QueryInterface(newDocShell); nsCOMPtr<nsIDOMStorageManager> newStorageManager = do_QueryInterface(newDocShell);
@ -1278,7 +1284,6 @@ nsWindowWatcher::GetWindowByName(const char16_t *aTargetName,
if (!aResult) { if (!aResult) {
return NS_ERROR_INVALID_ARG; return NS_ERROR_INVALID_ARG;
} }
nsresult rv;
*aResult = nullptr; *aResult = nullptr;
@ -1288,18 +1293,18 @@ nsWindowWatcher::GetWindowByName(const char16_t *aTargetName,
GetWindowTreeItem(aCurrentWindow, getter_AddRefs(startItem)); GetWindowTreeItem(aCurrentWindow, getter_AddRefs(startItem));
if (startItem) { if (startItem) {
// Note: original requestor is null here, per idl comments // Note: original requestor is null here, per idl comments
rv = startItem->FindItemWithName(aTargetName, nullptr, nullptr, startItem->FindItemWithName(aTargetName, nullptr, nullptr,
getter_AddRefs(treeItem)); getter_AddRefs(treeItem));
} }
else { else {
// Note: original requestor is null here, per idl comments // Note: original requestor is null here, per idl comments
rv = FindItemWithName(aTargetName, nullptr, nullptr, getter_AddRefs(treeItem)); FindItemWithName(aTargetName, nullptr, nullptr, getter_AddRefs(treeItem));
} }
nsCOMPtr<nsIDOMWindow> domWindow = do_GetInterface(treeItem); nsCOMPtr<nsIDOMWindow> domWindow = do_GetInterface(treeItem);
domWindow.swap(*aResult); domWindow.swap(*aResult);
return rv; return NS_OK;
} }
bool bool
@ -1705,14 +1710,10 @@ nsWindowWatcher::GetCallerTreeItem(nsIDocShellTreeItem* aParentItem)
return callerItem.forget(); return callerItem.forget();
} }
nsresult already_AddRefed<nsIDOMWindow>
nsWindowWatcher::SafeGetWindowByName(const nsAString& aName, nsWindowWatcher::SafeGetWindowByName(const nsAString& aName,
nsIDOMWindow* aCurrentWindow, nsIDOMWindow* aCurrentWindow)
nsIDOMWindow** aResult)
{ {
*aResult = nullptr;
nsresult rv;
nsCOMPtr<nsIDocShellTreeItem> startItem; nsCOMPtr<nsIDocShellTreeItem> startItem;
GetWindowTreeItem(aCurrentWindow, getter_AddRefs(startItem)); GetWindowTreeItem(aCurrentWindow, getter_AddRefs(startItem));
@ -1722,17 +1723,16 @@ nsWindowWatcher::SafeGetWindowByName(const nsAString& aName,
nsCOMPtr<nsIDocShellTreeItem> foundItem; nsCOMPtr<nsIDocShellTreeItem> foundItem;
if (startItem) { if (startItem) {
rv = startItem->FindItemWithName(flatName.get(), nullptr, callerItem, startItem->FindItemWithName(flatName.get(), nullptr, callerItem,
getter_AddRefs(foundItem)); getter_AddRefs(foundItem));
} }
else { else {
rv = FindItemWithName(flatName.get(), nullptr, callerItem, FindItemWithName(flatName.get(), nullptr, callerItem,
getter_AddRefs(foundItem)); getter_AddRefs(foundItem));
} }
nsCOMPtr<nsIDOMWindow> foundWin = do_GetInterface(foundItem); nsCOMPtr<nsIDOMWindow> foundWin = do_GetInterface(foundItem);
foundWin.swap(*aResult); return foundWin.forget();
return rv;
} }
/* Fetch the nsIDOMWindow corresponding to the given nsIDocShellTreeItem. /* Fetch the nsIDOMWindow corresponding to the given nsIDocShellTreeItem.

View File

@ -64,9 +64,8 @@ protected:
// Unlike GetWindowByName this will look for a caller on the JS // Unlike GetWindowByName this will look for a caller on the JS
// stack, and then fall back on aCurrentWindow if it can't find one. // stack, and then fall back on aCurrentWindow if it can't find one.
nsresult SafeGetWindowByName(const nsAString& aName, already_AddRefed<nsIDOMWindow>
nsIDOMWindow* aCurrentWindow, SafeGetWindowByName(const nsAString& aName, nsIDOMWindow* aCurrentWindow);
nsIDOMWindow** aResult);
// Just like OpenWindowJS, but knows whether it got called via OpenWindowJS // Just like OpenWindowJS, but knows whether it got called via OpenWindowJS
// (which means called from script) or called via OpenWindow. // (which means called from script) or called via OpenWindow.