mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
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:
parent
aabad2abb4
commit
d8885ccdf2
@ -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)) {
|
||||||
|
@ -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;
|
||||||
|
@ -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
|
||||||
|
@ -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__ */
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
};
|
};
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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.
|
||||||
|
@ -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.
|
||||||
|
Loading…
Reference in New Issue
Block a user