mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-28 07:13:20 +00:00
Bug 1331740: Pass correct context for TYPE_DOCUMENT loads within docshell. r=smaug
This commit is contained in:
parent
0edfbc2d51
commit
1b8c06e845
@ -9976,39 +9976,26 @@ nsDocShell::InternalLoad(nsIURI* aURI,
|
||||
|
||||
// If there's no targetDocShell, that means we are about to create a new
|
||||
// window (or aWindowTarget is empty). Perform a content policy check before
|
||||
// creating the window.
|
||||
if (!targetDocShell) {
|
||||
nsCOMPtr<Element> requestingElement;
|
||||
// creating the window. Please note for all other docshell loads
|
||||
// content policy checks are performed within the contentSecurityManager
|
||||
// when the channel is about to be openend.
|
||||
if (!targetDocShell && !aWindowTarget.IsEmpty()) {
|
||||
MOZ_ASSERT(contentType == nsIContentPolicy::TYPE_DOCUMENT,
|
||||
"opening a new window requires type to be TYPE_DOCUMENT");
|
||||
|
||||
nsISupports* requestingContext = nullptr;
|
||||
|
||||
if (contentType == nsIContentPolicy::TYPE_DOCUMENT) {
|
||||
if (XRE_IsContentProcess()) {
|
||||
// In e10s the child process doesn't have access to the element that
|
||||
// contains the browsing context (because that element is in the chrome
|
||||
// process). So we just pass mScriptGlobal.
|
||||
requestingContext = ToSupports(mScriptGlobal);
|
||||
} else {
|
||||
// This is for loading non-e10s tabs and toplevel windows of various
|
||||
// sorts.
|
||||
// For the toplevel window cases, requestingElement will be null.
|
||||
requestingElement = mScriptGlobal->AsOuter()->GetFrameElementInternal();
|
||||
requestingContext = requestingElement;
|
||||
}
|
||||
if (XRE_IsContentProcess()) {
|
||||
// In e10s the child process doesn't have access to the element that
|
||||
// contains the browsing context (because that element is in the chrome
|
||||
// process). So we just pass mScriptGlobal.
|
||||
requestingContext = ToSupports(mScriptGlobal);
|
||||
} else {
|
||||
requestingElement = mScriptGlobal->AsOuter()->GetFrameElementInternal();
|
||||
// This is for loading non-e10s tabs and toplevel windows of various
|
||||
// sorts.
|
||||
// For the toplevel window cases, requestingElement will be null.
|
||||
nsCOMPtr<Element> requestingElement =
|
||||
mScriptGlobal->AsOuter()->GetFrameElementInternal();
|
||||
requestingContext = requestingElement;
|
||||
|
||||
#ifdef DEBUG
|
||||
if (requestingElement) {
|
||||
// Get the docshell type for requestingElement.
|
||||
nsCOMPtr<nsIDocument> requestingDoc = requestingElement->OwnerDoc();
|
||||
nsCOMPtr<nsIDocShell> elementDocShell = requestingDoc->GetDocShell();
|
||||
|
||||
// requestingElement docshell type = current docshell type.
|
||||
MOZ_ASSERT(mItemType == elementDocShell->ItemType(),
|
||||
"subframes should have the same docshell type as their parent");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// Since Content Policy checks are performed within docShell as well as
|
||||
@ -11094,17 +11081,40 @@ nsDocShell::DoURILoad(nsIURI* aURI,
|
||||
nsCOMPtr<nsINode> loadingNode;
|
||||
nsCOMPtr<nsPIDOMWindowOuter> loadingWindow;
|
||||
nsCOMPtr<nsIPrincipal> loadingPrincipal;
|
||||
nsCOMPtr<nsISupports> topLevelLoadingContext;
|
||||
|
||||
if (aContentPolicyType == nsIContentPolicy::TYPE_DOCUMENT) {
|
||||
loadingNode = nullptr;
|
||||
loadingPrincipal = nullptr;
|
||||
loadingWindow = mScriptGlobal->AsOuter();
|
||||
if (XRE_IsContentProcess()) {
|
||||
// In e10s the child process doesn't have access to the element that
|
||||
// contains the browsing context (because that element is in the chrome
|
||||
// process).
|
||||
nsCOMPtr<nsITabChild> tabChild = GetTabChild();
|
||||
topLevelLoadingContext = ToSupports(tabChild);
|
||||
} else {
|
||||
// This is for loading non-e10s tabs and toplevel windows of various
|
||||
// sorts.
|
||||
// For the toplevel window cases, requestingElement will be null.
|
||||
nsCOMPtr<Element> requestingElement =
|
||||
loadingWindow->GetFrameElementInternal();
|
||||
topLevelLoadingContext = requestingElement;
|
||||
}
|
||||
} else {
|
||||
loadingWindow = nullptr;
|
||||
loadingNode = mScriptGlobal->AsOuter()->GetFrameElementInternal();
|
||||
if (loadingNode) {
|
||||
// If we have a loading node, then use that as our loadingPrincipal.
|
||||
loadingPrincipal = loadingNode->NodePrincipal();
|
||||
#ifdef DEBUG
|
||||
// Get the docshell type for requestingElement.
|
||||
nsCOMPtr<nsIDocument> requestingDoc = loadingNode->OwnerDoc();
|
||||
nsCOMPtr<nsIDocShell> elementDocShell = requestingDoc->GetDocShell();
|
||||
// requestingElement docshell type = current docshell type.
|
||||
MOZ_ASSERT(mItemType == elementDocShell->ItemType(),
|
||||
"subframes should have the same docshell type as their parent");
|
||||
#endif
|
||||
} else {
|
||||
// If this isn't a top-level load and mScriptGlobal's frame element is
|
||||
// null, then the element got removed from the DOM while we were trying
|
||||
@ -11165,7 +11175,7 @@ nsDocShell::DoURILoad(nsIURI* aURI,
|
||||
|
||||
nsCOMPtr<nsILoadInfo> loadInfo =
|
||||
(aContentPolicyType == nsIContentPolicy::TYPE_DOCUMENT) ?
|
||||
new LoadInfo(loadingWindow, aTriggeringPrincipal,
|
||||
new LoadInfo(loadingWindow, aTriggeringPrincipal, topLevelLoadingContext,
|
||||
securityFlags) :
|
||||
new LoadInfo(loadingPrincipal, aTriggeringPrincipal, loadingNode,
|
||||
securityFlags, aContentPolicyType);
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "nsIDOMElement.h"
|
||||
#include "nsIDOMNode.h"
|
||||
#include "nsIDOMWindow.h"
|
||||
#include "nsITabChild.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsIImageLoadingContent.h"
|
||||
#include "nsILoadContext.h"
|
||||
@ -93,8 +94,9 @@ nsContentPolicy::CheckPolicy(CPMethod policyMethod,
|
||||
{
|
||||
nsCOMPtr<nsIDOMNode> node(do_QueryInterface(requestingContext));
|
||||
nsCOMPtr<nsIDOMWindow> window(do_QueryInterface(requestingContext));
|
||||
NS_ASSERTION(!requestingContext || node || window,
|
||||
"Context should be a DOM node or a DOM window!");
|
||||
nsCOMPtr<nsITabChild> tabChild(do_QueryInterface(requestingContext));
|
||||
NS_ASSERTION(!requestingContext || node || window || tabChild,
|
||||
"Context should be a DOM node, DOM window or a tabChild!");
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -175,7 +175,7 @@ DoContentSecurityChecks(nsIChannel* aChannel, nsILoadInfo* aLoadInfo)
|
||||
nsContentPolicyType internalContentPolicyType =
|
||||
aLoadInfo->InternalContentPolicyType();
|
||||
nsCString mimeTypeGuess;
|
||||
nsCOMPtr<nsINode> requestingContext = nullptr;
|
||||
nsCOMPtr<nsISupports> requestingContext = nullptr;
|
||||
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
nsresult rv = NS_GetFinalChannelURI(aChannel, getter_AddRefs(uri));
|
||||
@ -229,7 +229,7 @@ DoContentSecurityChecks(nsIChannel* aChannel, nsILoadInfo* aLoadInfo)
|
||||
|
||||
case nsIContentPolicy::TYPE_DOCUMENT: {
|
||||
mimeTypeGuess = EmptyCString();
|
||||
requestingContext = aLoadInfo->LoadingNode();
|
||||
requestingContext = aLoadInfo->ContextForTopLevelLoad();
|
||||
break;
|
||||
}
|
||||
|
||||
@ -259,10 +259,13 @@ DoContentSecurityChecks(nsIChannel* aChannel, nsILoadInfo* aLoadInfo)
|
||||
case nsIContentPolicy::TYPE_XMLHTTPREQUEST: {
|
||||
// alias nsIContentPolicy::TYPE_DATAREQUEST:
|
||||
requestingContext = aLoadInfo->LoadingNode();
|
||||
MOZ_ASSERT(!requestingContext ||
|
||||
requestingContext->NodeType() == nsIDOMNode::DOCUMENT_NODE,
|
||||
"type_xml requires requestingContext of type Document");
|
||||
|
||||
#ifdef DEBUG
|
||||
{
|
||||
nsCOMPtr<nsINode> node = do_QueryInterface(requestingContext);
|
||||
MOZ_ASSERT(!node || node->NodeType() == nsIDOMNode::DOCUMENT_NODE,
|
||||
"type_xml requires requestingContext of type Document");
|
||||
}
|
||||
#endif
|
||||
// We're checking for the external TYPE_XMLHTTPREQUEST here in case
|
||||
// an addon creates a request with that type.
|
||||
if (internalContentPolicyType ==
|
||||
@ -283,18 +286,26 @@ DoContentSecurityChecks(nsIChannel* aChannel, nsILoadInfo* aLoadInfo)
|
||||
case nsIContentPolicy::TYPE_OBJECT_SUBREQUEST: {
|
||||
mimeTypeGuess = EmptyCString();
|
||||
requestingContext = aLoadInfo->LoadingNode();
|
||||
MOZ_ASSERT(!requestingContext ||
|
||||
requestingContext->NodeType() == nsIDOMNode::ELEMENT_NODE,
|
||||
"type_subrequest requires requestingContext of type Element");
|
||||
#ifdef DEBUG
|
||||
{
|
||||
nsCOMPtr<nsINode> node = do_QueryInterface(requestingContext);
|
||||
MOZ_ASSERT(!node || node->NodeType() == nsIDOMNode::ELEMENT_NODE,
|
||||
"type_subrequest requires requestingContext of type Element");
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
case nsIContentPolicy::TYPE_DTD: {
|
||||
mimeTypeGuess = EmptyCString();
|
||||
requestingContext = aLoadInfo->LoadingNode();
|
||||
MOZ_ASSERT(!requestingContext ||
|
||||
requestingContext->NodeType() == nsIDOMNode::DOCUMENT_NODE,
|
||||
"type_dtd requires requestingContext of type Document");
|
||||
#ifdef DEBUG
|
||||
{
|
||||
nsCOMPtr<nsINode> node = do_QueryInterface(requestingContext);
|
||||
MOZ_ASSERT(!node || node->NodeType() == nsIDOMNode::DOCUMENT_NODE,
|
||||
"type_dtd requires requestingContext of type Document");
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
@ -312,9 +323,13 @@ DoContentSecurityChecks(nsIChannel* aChannel, nsILoadInfo* aLoadInfo)
|
||||
mimeTypeGuess = EmptyCString();
|
||||
}
|
||||
requestingContext = aLoadInfo->LoadingNode();
|
||||
MOZ_ASSERT(!requestingContext ||
|
||||
requestingContext->NodeType() == nsIDOMNode::ELEMENT_NODE,
|
||||
"type_media requires requestingContext of type Element");
|
||||
#ifdef DEBUG
|
||||
{
|
||||
nsCOMPtr<nsINode> node = do_QueryInterface(requestingContext);
|
||||
MOZ_ASSERT(!node || node->NodeType() == nsIDOMNode::ELEMENT_NODE,
|
||||
"type_media requires requestingContext of type Element");
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
@ -342,18 +357,26 @@ DoContentSecurityChecks(nsIChannel* aChannel, nsILoadInfo* aLoadInfo)
|
||||
case nsIContentPolicy::TYPE_XSLT: {
|
||||
mimeTypeGuess = NS_LITERAL_CSTRING("application/xml");
|
||||
requestingContext = aLoadInfo->LoadingNode();
|
||||
MOZ_ASSERT(!requestingContext ||
|
||||
requestingContext->NodeType() == nsIDOMNode::DOCUMENT_NODE,
|
||||
"type_xslt requires requestingContext of type Document");
|
||||
#ifdef DEBUG
|
||||
{
|
||||
nsCOMPtr<nsINode> node = do_QueryInterface(requestingContext);
|
||||
MOZ_ASSERT(!node || node->NodeType() == nsIDOMNode::DOCUMENT_NODE,
|
||||
"type_xslt requires requestingContext of type Document");
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
case nsIContentPolicy::TYPE_BEACON: {
|
||||
mimeTypeGuess = EmptyCString();
|
||||
requestingContext = aLoadInfo->LoadingNode();
|
||||
MOZ_ASSERT(!requestingContext ||
|
||||
requestingContext->NodeType() == nsIDOMNode::DOCUMENT_NODE,
|
||||
"type_beacon requires requestingContext of type Document");
|
||||
#ifdef DEBUG
|
||||
{
|
||||
nsCOMPtr<nsINode> node = do_QueryInterface(requestingContext);
|
||||
MOZ_ASSERT(!node || node->NodeType() == nsIDOMNode::DOCUMENT_NODE,
|
||||
"type_beacon requires requestingContext of type Document");
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -40,6 +40,7 @@ LoadInfo::LoadInfo(nsIPrincipal* aLoadingPrincipal,
|
||||
aTriggeringPrincipal : mLoadingPrincipal.get())
|
||||
, mPrincipalToInherit(nullptr)
|
||||
, mLoadingContext(do_GetWeakReference(aLoadingContext))
|
||||
, mContextForTopLevelLoad(nullptr)
|
||||
, mSecurityFlags(aSecurityFlags)
|
||||
, mInternalContentPolicyType(aContentPolicyType)
|
||||
, mTainting(LoadTainting::Basic)
|
||||
@ -211,10 +212,12 @@ LoadInfo::LoadInfo(nsIPrincipal* aLoadingPrincipal,
|
||||
*/
|
||||
LoadInfo::LoadInfo(nsPIDOMWindowOuter* aOuterWindow,
|
||||
nsIPrincipal* aTriggeringPrincipal,
|
||||
nsISupports* aContextForTopLevelLoad,
|
||||
nsSecurityFlags aSecurityFlags)
|
||||
: mLoadingPrincipal(nullptr)
|
||||
, mTriggeringPrincipal(aTriggeringPrincipal)
|
||||
, mPrincipalToInherit(nullptr)
|
||||
, mContextForTopLevelLoad(do_GetWeakReference(aContextForTopLevelLoad))
|
||||
, mSecurityFlags(aSecurityFlags)
|
||||
, mInternalContentPolicyType(nsIContentPolicy::TYPE_DOCUMENT)
|
||||
, mTainting(LoadTainting::Basic)
|
||||
@ -276,6 +279,7 @@ LoadInfo::LoadInfo(const LoadInfo& rhs)
|
||||
, mSandboxedLoadingPrincipal(rhs.mSandboxedLoadingPrincipal)
|
||||
, mResultPrincipalURI(rhs.mResultPrincipalURI)
|
||||
, mLoadingContext(rhs.mLoadingContext)
|
||||
, mContextForTopLevelLoad(rhs.mContextForTopLevelLoad)
|
||||
, mSecurityFlags(rhs.mSecurityFlags)
|
||||
, mInternalContentPolicyType(rhs.mInternalContentPolicyType)
|
||||
, mTainting(rhs.mTainting)
|
||||
@ -511,6 +515,17 @@ LoadInfo::LoadingNode()
|
||||
return node;
|
||||
}
|
||||
|
||||
nsISupports*
|
||||
LoadInfo::ContextForTopLevelLoad()
|
||||
{
|
||||
// Most likely you want to query LoadingNode() instead of
|
||||
// ContextForTopLevelLoad() if this assertion fires.
|
||||
MOZ_ASSERT(mInternalContentPolicyType == nsIContentPolicy::TYPE_DOCUMENT,
|
||||
"should only query this context for top level document loads");
|
||||
nsCOMPtr<nsISupports> context = do_QueryReferent(mContextForTopLevelLoad);
|
||||
return context;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
LoadInfo::GetSecurityFlags(nsSecurityFlags* aResult)
|
||||
{
|
||||
|
@ -56,10 +56,12 @@ public:
|
||||
nsSecurityFlags aSecurityFlags,
|
||||
nsContentPolicyType aContentPolicyType);
|
||||
|
||||
// Constructor used for TYPE_DOCUMENT loads which have no reasonable
|
||||
// loadingNode or loadingPrincipal
|
||||
// Constructor used for TYPE_DOCUMENT loads which have a different
|
||||
// loadingContext than other loads. This ContextForTopLevelLoad is
|
||||
// only used for content policy checks.
|
||||
LoadInfo(nsPIDOMWindowOuter* aOuterWindow,
|
||||
nsIPrincipal* aTriggeringPrincipal,
|
||||
nsISupports* aContextForTopLevelLoad,
|
||||
nsSecurityFlags aSecurityFlags);
|
||||
|
||||
// create an exact copy of the loadinfo
|
||||
@ -146,6 +148,7 @@ private:
|
||||
nsCOMPtr<nsIPrincipal> mSandboxedLoadingPrincipal;
|
||||
nsCOMPtr<nsIURI> mResultPrincipalURI;
|
||||
nsWeakPtr mLoadingContext;
|
||||
nsWeakPtr mContextForTopLevelLoad;
|
||||
nsSecurityFlags mSecurityFlags;
|
||||
nsContentPolicyType mInternalContentPolicyType;
|
||||
LoadTainting mTainting;
|
||||
|
@ -331,6 +331,16 @@ interface nsILoadInfo : nsISupports
|
||||
[noscript, notxpcom, nostdcall, binaryname(LoadingNode)]
|
||||
nsINode binaryLoadingNode();
|
||||
|
||||
/**
|
||||
* A C++ friendly version of the loadingContext for toplevel loads.
|
||||
* Most likely you want to query the ownerDocument or LoadingNode
|
||||
* and not this context only available for TYPE_DOCUMENT loads.
|
||||
* Please note that except for loads of TYPE_DOCUMENT, this
|
||||
* ContextForTopLevelLoad will always return null.
|
||||
*/
|
||||
[noscript, notxpcom, nostdcall, binaryname(ContextForTopLevelLoad)]
|
||||
nsISupports binaryContextForTopLevelLoad();
|
||||
|
||||
/**
|
||||
* The securityFlags of that channel.
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user