Push up GetPrincipal to nsINode (as GetNodePrincipal). This way all nsINodes

(content, documents, attr nodes) can return their principal as needed.
Eliminate lazy allocation of principals in nsDocument.  Bug 324600, r=sicking, sr=jst
This commit is contained in:
bzbarsky%mit.edu 2006-02-02 20:02:34 +00:00
parent 3cdb5fa370
commit 263cf7dc11
48 changed files with 308 additions and 479 deletions

View File

@ -427,10 +427,6 @@ public:
return sWordBreaker;
}
static nsresult GetDocumentAndPrincipal(nsIDOMNode* aNode,
nsIDocument** aDocument,
nsIPrincipal** aPrincipal);
/**
* @return PR_TRUE if aContent has an attribute aName in namespace aNameSpaceID,
* and the attribute value is non-empty.

View File

@ -50,8 +50,8 @@ class nsIAtom;
class nsDOMAttributeMap;
#define NS_IATTRIBUTE_IID \
{ 0x629c4659, 0xbadd, 0x4364, \
{ 0x88, 0x9f, 0x37, 0x66, 0x70, 0xbe, 0x1a, 0xee } }
{ 0xba2a0ee1, 0x2484, 0x49d7, \
{ 0xb5, 0x3c, 0xc8, 0xe4, 0x82, 0x9d, 0xa4, 0xf2 } }
class nsIAttribute : public nsINode
{

View File

@ -64,10 +64,10 @@ class nsAttrValue;
class nsAttrName;
// IID for the nsIContent interface
// bb761f7a-62a8-43d4-9694-1cf7850b0453
// b61222e2-88b6-4f7f-ae81-679484a4493a
#define NS_ICONTENT_IID \
{ 0xbb761f7a, 0x62a8, 0x43d4, \
{ 0x96, 0x94, 0x1c, 0xf7, 0x85, 0x0b, 0x04, 0x53 } }
{ 0xb61222e2, 0x88b6, 0x4f7f, \
{ 0xae, 0x81, 0x67, 0x94, 0x84, 0xa4, 0x49, 0x3a } }
/**
* A node of content in a document's content model. This interface

View File

@ -91,10 +91,10 @@ class nsIVariant;
class nsIDOMUserDataHandler;
// IID for the nsIDocument interface
// bc831b59-2148-4016-a3c8-bf65f68da758
// 0a87ec89-5589-4690-93b9-6c6c86e1e072
#define NS_IDOCUMENT_IID \
{ 0xbc831b59, 0x2148, 0x4016, \
{ 0xa3, 0xc8, 0xbf, 0x65, 0xf6, 0x8d, 0xa7, 0x58 } }
{ 0x0a87ec89, 0x5589, 0x4690, \
{ 0x93, 0xb9, 0x6c, 0x6c, 0x86, 0xe1, 0xe0, 0x72 } }
// Flag for AddStyleSheet().
#define NS_STYLESHEET_FROM_CATALOG (1 << 0)
@ -173,11 +173,6 @@ public:
mDocumentURI = aURI;
}
/**
* Return the principal responsible for this document.
*/
virtual nsIPrincipal* GetPrincipal() = 0;
/**
* Set the principal responsible for this document.
*/

View File

@ -48,12 +48,13 @@
class nsIContent;
class nsIDocument;
class nsIPrincipal;
// IID for the nsINode interface
// 9c74e48b-b417-4058-aa23-83cd7eb15131
// 6b7a8e08-f34b-4210-af93-ec7a769498e9
#define NS_INODE_IID \
{ 0x9c74e48b, 0xb417, 0x4058, \
{ 0xaa, 0x23, 0x83, 0xcd, 0x7e, 0xb1, 0x51, 0x31 } }
{ 0x6b7a8e08, 0xf34b, 0x4210, \
{ 0xaf, 0x93, 0xec, 0x7a, 0x76, 0x94, 0x98, 0xe9 } }
/**
* An internal interface that abstracts some DOMNode-related parts that both
@ -224,6 +225,15 @@ public:
*/
virtual void* UnsetProperty(nsIAtom *aPropertyName,
nsresult *aStatus = nsnull);
/**
* Return the principal of this node. This may return null; in that case the
* caller should assume that all same-origin checks against this node fail
* and that this node has no permissions to do anything.
*/
nsIPrincipal* GetNodePrincipal() const {
return mNodeInfo->NodeInfoManager()->GetDocumentPrincipal();
}
/**
* IsNodeOfType()? Do we need a non-QI way to tell apart documents and

View File

@ -563,9 +563,9 @@ nsContentAreaDragDrop::DragDrop(nsIDOMEvent* inMouseEvent)
session->GetSourceDocument(getter_AddRefs(sourceDocument));
nsCOMPtr<nsIDocument> sourceDoc(do_QueryInterface(sourceDocument));
if (sourceDoc && sourceDoc->GetPrincipal()) {
if (sourceDoc && sourceDoc->GetNodePrincipal()) {
nsCOMPtr<nsIURI> sourceUri;
sourceDoc->GetPrincipal()->GetURI(getter_AddRefs(sourceUri));
sourceDoc->GetNodePrincipal()->GetURI(getter_AddRefs(sourceUri));
if (sourceUri) {
nsCAutoString sourceUriStr;

View File

@ -328,7 +328,7 @@ nsContentSink::ProcessHeaderData(nsIAtom* aHeader, const nsAString& aValue,
// We use the original codebase in case the codebase was changed
// by SetDomain
nsIPrincipal *docPrincipal = mDocument->GetPrincipal();
nsIPrincipal *docPrincipal = mDocument->GetNodePrincipal();
if (!docPrincipal) {
return NS_ERROR_FAILURE;
}

View File

@ -493,68 +493,6 @@ nsContentUtils::GetClassInfoInstance(nsDOMClassInfoID aID)
return sDOMScriptObjectFactory->GetClassInfoInstance(aID);
}
// static
nsresult
nsContentUtils::GetDocumentAndPrincipal(nsIDOMNode* aNode,
nsIDocument** aDocument,
nsIPrincipal** aPrincipal)
{
// For performance reasons it's important to try to QI the node to
// nsIContent before trying to QI to nsIDocument since a QI miss on
// a node is potentially expensive.
nsCOMPtr<nsIContent> content = do_QueryInterface(aNode);
nsCOMPtr<nsIAttribute> attr;
if (!content) {
CallQueryInterface(aNode, aDocument);
if (!*aDocument) {
attr = do_QueryInterface(aNode);
if (!attr) {
// aNode is not a nsIContent, a nsIAttribute or a nsIDocument,
// something weird is going on...
NS_ERROR("aNode is not nsIContent, nsIAttribute or nsIDocument!");
return NS_ERROR_UNEXPECTED;
}
}
}
if (!*aDocument) {
nsCOMPtr<nsIDOMDocument> domDoc;
aNode->GetOwnerDocument(getter_AddRefs(domDoc));
if (!domDoc) {
// if we can't get a doc then lets try to get principal through nodeinfo
// manager
nsINodeInfo *ni = content ? content->NodeInfo() : attr->NodeInfo();
*aPrincipal = ni->NodeInfoManager()->GetDocumentPrincipal();
if (!*aPrincipal) {
// we can't get to the principal so we'll give up
return NS_OK;
}
NS_ADDREF(*aPrincipal);
}
else {
CallQueryInterface(domDoc, aDocument);
if (!*aDocument) {
NS_ERROR("QI to nsIDocument failed");
return NS_ERROR_UNEXPECTED;
}
}
}
if (!*aPrincipal) {
NS_IF_ADDREF(*aPrincipal = (*aDocument)->GetPrincipal());
}
return NS_OK;
}
/**
* Checks whether two nodes come from the same origin. aTrustedNode is
* considered 'safe' in that a user can operate on it and that it isn't
@ -578,83 +516,24 @@ nsContentUtils::CheckSameOrigin(nsIDOMNode *aTrustedNode,
}
/*
* Get hold of each node's document or principal
* Get hold of each node's principal
*/
nsCOMPtr<nsINode> trustedNode = do_QueryInterface(aTrustedNode);
nsCOMPtr<nsINode> unTrustedNode = do_QueryInterface(aUnTrustedNode);
// In most cases this is a document, so lets try that first
nsCOMPtr<nsIDocument> trustedDoc = do_QueryInterface(aTrustedNode);
nsIPrincipal* trustedPrincipal = nsnull;
// Make sure these are both real nodes
NS_ENSURE_TRUE(trustedNode && unTrustedNode, NS_ERROR_UNEXPECTED);
if (!trustedDoc) {
#ifdef DEBUG
nsCOMPtr<nsIContent> trustCont = do_QueryInterface(aTrustedNode);
NS_ASSERTION(trustCont,
"aTrustedNode is neither nsIContent nor nsIDocument!");
#endif
nsCOMPtr<nsIDOMDocument> domDoc;
aTrustedNode->GetOwnerDocument(getter_AddRefs(domDoc));
nsIPrincipal* trustedPrincipal = trustedNode->GetNodePrincipal();
nsIPrincipal* unTrustedPrincipal = unTrustedNode->GetNodePrincipal();
if (!domDoc) {
// In theory this should never happen. But since theory and reality are
// different for XUL elements we'll try to get the principal from the
// nsNodeInfoManager.
nsCOMPtr<nsIContent> cont = do_QueryInterface(aTrustedNode);
NS_ENSURE_TRUE(cont, NS_ERROR_UNEXPECTED);
trustedPrincipal = cont->NodeInfo()->NodeInfoManager()->
GetDocumentPrincipal();
if (!trustedPrincipal) {
// Can't get principal of aTrustedNode so we can't check security
// against it
return NS_ERROR_UNEXPECTED;
}
} else {
trustedDoc = do_QueryInterface(domDoc);
NS_ASSERTION(trustedDoc, "QI to nsIDocument failed");
}
}
nsCOMPtr<nsIDocument> unTrustedDoc;
nsCOMPtr<nsIPrincipal> unTrustedPrincipal;
nsresult rv = GetDocumentAndPrincipal(aUnTrustedNode,
getter_AddRefs(unTrustedDoc),
getter_AddRefs(unTrustedPrincipal));
NS_ENSURE_SUCCESS(rv, rv);
if (!unTrustedDoc && !unTrustedPrincipal) {
// We can't get hold of the principal for this node. This should happen
// very rarely, like for textnodes out of the tree and <option>s created
// using 'new Option'.
// If we didn't allow access to nodes like this you wouldn't be able to
// insert these nodes into a document.
// Make sure we have both principals
NS_ENSURE_TRUE(trustedPrincipal && unTrustedPrincipal, NS_ERROR_UNEXPECTED);
if (trustedPrincipal == unTrustedPrincipal) {
return NS_OK;
}
/*
* Compare the principals
*/
// If they are in the same document then everything is just fine
if (trustedDoc == unTrustedDoc && trustedDoc) {
return NS_OK;
}
if (!trustedPrincipal) {
trustedPrincipal = trustedDoc->GetPrincipal();
if (!trustedPrincipal) {
// If the trusted node doesn't have a principal we can't check
// security against it
return NS_ERROR_DOM_SECURITY_ERR;
}
}
return sSecurityManager->CheckSameOriginPrincipal(trustedPrincipal,
unTrustedPrincipal);
}
@ -663,6 +542,9 @@ nsContentUtils::CheckSameOrigin(nsIDOMNode *aTrustedNode,
PRBool
nsContentUtils::CanCallerAccess(nsIDOMNode *aNode)
{
// XXXbz why not check the IsCapabilityEnabled thing up front, and not bother
// with the system principal games? But really, there should be a simpler
// API here, dammit.
nsCOMPtr<nsIPrincipal> subjectPrincipal;
sSecurityManager->GetSubjectPrincipal(getter_AddRefs(subjectPrincipal));
@ -681,26 +563,18 @@ nsContentUtils::CanCallerAccess(nsIDOMNode *aNode)
return PR_TRUE;
}
nsCOMPtr<nsIDocument> document;
nsCOMPtr<nsIPrincipal> principal;
nsCOMPtr<nsINode> node = do_QueryInterface(aNode);
NS_ENSURE_TRUE(node, PR_FALSE);
nsresult rv = GetDocumentAndPrincipal(aNode,
getter_AddRefs(document),
getter_AddRefs(principal));
NS_ENSURE_SUCCESS(rv, PR_FALSE);
nsIPrincipal* principal = node->GetNodePrincipal();
if (!document && !principal) {
// We can't get hold of the principal for this node. This should happen
// very rarely, like for textnodes out of the tree and <option>s created
// using 'new Option'.
// If we didn't allow access to nodes like this you wouldn't be able to
// insert these nodes into a document.
return PR_TRUE;
if (!principal) {
// We can't get hold of the principal for this node. No access allowed.
return PR_FALSE;
}
rv = sSecurityManager->CheckSameOriginPrincipal(subjectPrincipal,
principal);
nsresult rv = sSecurityManager->CheckSameOriginPrincipal(subjectPrincipal,
principal);
if (NS_SUCCEEDED(rv)) {
return PR_TRUE;
}
@ -1896,7 +1770,7 @@ nsContentUtils::CanLoadImage(nsIURI* aURI, nsISupports* aContext,
// Editor apps get special treatment here, editors can load images
// from anywhere.
rv = sSecurityManager->
CheckLoadURIWithPrincipal(aLoadingDocument->GetPrincipal(), aURI,
CheckLoadURIWithPrincipal(aLoadingDocument->GetNodePrincipal(), aURI,
nsIScriptSecurityManager::ALLOW_CHROME);
if (NS_FAILED(rv)) {
if (aImageBlockingStatus) {
@ -2061,13 +1935,11 @@ nsContentUtils::GetXLinkURI(nsIContent* aContent)
{
NS_PRECONDITION(aContent, "Must have content node to work with");
nsAutoString value;
aContent->GetAttr(kNameSpaceID_XLink, nsHTMLAtoms::type, value);
if (value.EqualsLiteral("simple")) {
if (aContent->AttrValueIs(kNameSpaceID_XLink, nsGkAtoms::type,
nsGkAtoms::simple, eCaseMatters)) {
nsAutoString value;
// Check that we have a URI
aContent->GetAttr(kNameSpaceID_XLink, nsHTMLAtoms::href, value);
if (!value.IsEmpty()) {
if (aContent->GetAttr(kNameSpaceID_XLink, nsHTMLAtoms::href, value)) {
// Resolve it relative to aContent's base URI.
nsCOMPtr<nsIURI> baseURI = aContent->GetBaseURI();
@ -2413,7 +2285,7 @@ PRBool
nsContentUtils::IsChromeDoc(nsIDocument *aDocument)
{
nsIPrincipal *principal;
if (!aDocument || !(principal = aDocument->GetPrincipal())) {
if (!aDocument || !(principal = aDocument->GetNodePrincipal())) {
return PR_FALSE;
}

View File

@ -551,6 +551,7 @@ nsDOMImplementation::CreateDocumentType(const nsAString& aQualifiedName,
nsCOMPtr<nsIAtom> name = do_GetAtom(aQualifiedName);
NS_ENSURE_TRUE(name, NS_ERROR_OUT_OF_MEMORY);
// XXXbz shouldn't this use the original document principal instead?
nsCOMPtr<nsIPrincipal> principal;
rv = nsContentUtils::GetSecurityManager()->
GetCodebasePrincipal(mBaseURI, getter_AddRefs(principal));
@ -928,9 +929,12 @@ nsDocument::Reset(nsIChannel* aChannel, nsILoadGroup* aLoadGroup)
if (aChannel) {
nsCOMPtr<nsISupports> owner;
aChannel->GetOwner(getter_AddRefs(owner));
mPrincipal = do_QueryInterface(owner);
if (NS_SUCCEEDED(aChannel->GetOwner(getter_AddRefs(owner)))) {
nsCOMPtr<nsIPrincipal> principal = do_QueryInterface(owner);
if (principal) {
SetPrincipal(principal);
}
}
}
mChannel = aChannel;
@ -951,7 +955,7 @@ nsDocument::ResetToURI(nsIURI *aURI, nsILoadGroup *aLoadGroup)
mDocumentTitle.SetIsVoid(PR_TRUE);
mPrincipal = nsnull;
SetPrincipal(nsnull);
mSecurityInfo = nsnull;
mDocumentLoadGroup = nsnull;
@ -1004,6 +1008,19 @@ nsDocument::ResetToURI(nsIURI *aURI, nsILoadGroup *aLoadGroup)
mReferrer.Truncate();
mXMLDeclarationBits = 0;
// Now get our new principal
nsIScriptSecurityManager *securityManager =
nsContentUtils::GetSecurityManager();
if (securityManager) {
nsCOMPtr<nsIPrincipal> principal;
nsresult rv =
securityManager->GetCodebasePrincipal(mDocumentURI,
getter_AddRefs(principal));
if (NS_SUCCEEDED(rv)) {
SetPrincipal(principal);
}
}
}
nsresult
@ -1210,31 +1227,13 @@ nsDocument::GetLastModified(nsAString& aLastModified)
nsIPrincipal*
nsDocument::GetPrincipal()
{
if (!mPrincipal) {
nsIScriptSecurityManager *securityManager =
nsContentUtils::GetSecurityManager();
if (!securityManager) {
return nsnull;
}
NS_WARN_IF_FALSE(mDocumentURI, "no URI!");
nsresult rv =
securityManager->GetCodebasePrincipal(mDocumentURI,
getter_AddRefs(mPrincipal));
if (NS_FAILED(rv)) {
return nsnull;
}
}
return mPrincipal;
return GetNodePrincipal();
}
void
nsDocument::SetPrincipal(nsIPrincipal *aNewPrincipal)
{
mPrincipal = aNewPrincipal;
mNodeInfoManager->SetDocumentPrincipal(aNewPrincipal);
}
NS_IMETHODIMP
@ -1268,7 +1267,7 @@ nsDocument::SetBaseURI(nsIURI* aURI)
nsresult rv = NS_OK;
if (aURI) {
nsIPrincipal* principal = GetPrincipal();
nsIPrincipal* principal = GetNodePrincipal();
NS_ENSURE_TRUE(principal, NS_ERROR_FAILURE);
nsIScriptSecurityManager* securityManager =
@ -4643,7 +4642,7 @@ nsDocument::IsScriptEnabled()
nsCOMPtr<nsIScriptSecurityManager> sm(do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID));
NS_ENSURE_TRUE(sm, PR_TRUE);
nsIPrincipal* principal = GetPrincipal();
nsIPrincipal* principal = GetNodePrincipal();
NS_ENSURE_TRUE(principal, PR_TRUE);
nsIScriptGlobalObject* globalObject = GetScriptGlobalObject();

View File

@ -319,11 +319,6 @@ public:
virtual void StopDocumentLoad();
/**
* Return the principal responsible for this document.
*/
virtual nsIPrincipal* GetPrincipal();
/**
* Set the principal responsible for this document.
*/
@ -624,8 +619,7 @@ public:
NS_DECL_NSIDOMNSEVENTTARGET
// nsIScriptObjectPrincipal
// virtual nsIPrincipal* GetPrincipal();
// Already declared in nsIDocument
virtual nsIPrincipal* GetPrincipal();
virtual nsresult Init();
@ -714,7 +708,6 @@ protected:
nsCString mReferrer;
nsString mLastModified;
nsCOMPtr<nsIPrincipal> mPrincipal;
nsVoidArray mCharSetObservers;

View File

@ -162,7 +162,9 @@ nsFrameLoader::LoadURI(nsIURI* aURI)
// to inherit an owner from the current document.
loadInfo->SetInheritOwner(PR_TRUE);
principal = doc->GetPrincipal();
principal = mOwnerContent->GetNodePrincipal();
NS_ASSERTION(principal == doc->GetNodePrincipal(),
"Principal mismatch. Should not happen");
}
if (!principal) {

View File

@ -2440,7 +2440,7 @@ nsGenericElement::GetBaseURI() const
if (NS_SUCCEEDED(rv)) {
// do a security check, almost the same as nsDocument::SetBaseURL()
rv = nsContentUtils::GetSecurityManager()->
CheckLoadURIWithPrincipal(doc->GetPrincipal(), ourBase,
CheckLoadURIWithPrincipal(GetNodePrincipal(), ourBase,
nsIScriptSecurityManager::STANDARD);
}
@ -3673,7 +3673,6 @@ nsGenericElement::LeaveLink(nsPresContext* aPresContext)
nsresult
nsGenericElement::TriggerLink(nsPresContext* aPresContext,
nsLinkVerb aVerb,
nsIURI* aOriginURI,
nsIURI* aLinkURI,
const nsAFlatString& aTargetSpec,
PRBool aClick,
@ -3685,6 +3684,11 @@ nsGenericElement::TriggerLink(nsPresContext* aPresContext,
nsILinkHandler *handler = aPresContext->GetLinkHandler();
if (!handler) return NS_OK;
nsIPrincipal* principal = GetNodePrincipal();
if (!principal) {
return NS_OK;
}
if (aClick) {
nsresult proceed = NS_OK;
// Check that this page is allowed to load this URI.
@ -3695,7 +3699,7 @@ nsGenericElement::TriggerLink(nsPresContext* aPresContext,
(PRUint32) nsIScriptSecurityManager::STANDARD :
(PRUint32) nsIScriptSecurityManager::DISALLOW_FROM_MAIL;
proceed =
securityManager->CheckLoadURI(aOriginURI, aLinkURI, flag);
securityManager->CheckLoadURIWithPrincipal(principal, aLinkURI, flag);
}
// Only pass off the click event if the script security manager

View File

@ -541,11 +541,11 @@ public:
/**
* Trigger a link with uri aLinkURI. If aClick is false, this triggers a
* mouseover on the link, otherwise it triggers a load, after doing a
* security check.
* security check. The node principal of |this| is used for the security
* check.
*
* @param aPresContext the pres context.
* @param aVerb how the link will be loaded (replace page, new window, etc.)
* @param aOriginURI the URI the request originates from. Used as the origin
* uri for a CheckLoadURI call.
* @param aLinkURI the URI of the link
* @param aTargetSpec the target (like target=, may be empty)
* @param aClick whether this was a click or not (if false, it assumes you
@ -556,7 +556,6 @@ public:
*/
nsresult TriggerLink(nsPresContext* aPresContext,
nsLinkVerb aVerb,
nsIURI* aOriginURI,
nsIURI* aLinkURI,
const nsAFlatString& aTargetSpec,
PRBool aClick,

View File

@ -81,6 +81,7 @@ nsNodeInfoManager::NodeInfoInnerKeyCompare(const void *key1, const void *key2)
nsNodeInfoManager::nsNodeInfoManager()
: mDocument(nsnull),
mPrincipal(nsnull),
mTextNodeInfo(nsnull),
mCommentNodeInfo(nsnull),
mDocumentNodeInfo(nsnull)
@ -109,6 +110,8 @@ nsNodeInfoManager::~nsNodeInfoManager()
nsNodeInfo::ClearCache();
}
NS_IF_RELEASE(mPrincipal);
#ifdef DEBUG_jst
printf ("Removing NodeInfoManager, gcount = %d\n", gNodeManagerCount);
#endif
@ -147,9 +150,6 @@ nsNodeInfoManager::Init(nsIDocument *aDocument)
NS_ENSURE_TRUE(mNodeInfoHash, NS_ERROR_OUT_OF_MEMORY);
mDocument = aDocument;
if (aDocument) {
mPrincipal = nsnull;
}
return NS_OK;
}
@ -157,17 +157,6 @@ nsNodeInfoManager::Init(nsIDocument *aDocument)
void
nsNodeInfoManager::DropDocumentReference()
{
if (mDocument) {
// If the document has a uri we'll ask for it's principal. Otherwise we'll
// consider this document 'anonymous'. We don't want to call GetPrincipal
// on a document that doesn't have a URI since that'll give an assertion
// that we're creating a principal without having a uri.
// This happens in a few cases where a document is created and then
// immediately dropped without ever getting a URI.
if (mDocument->GetDocumentURI()) {
mPrincipal = mDocument->GetPrincipal();
}
}
mDocument = nsnull;
}
@ -304,33 +293,11 @@ nsNodeInfoManager::GetDocumentNodeInfo()
return mDocumentNodeInfo;
}
nsIPrincipal*
nsNodeInfoManager::GetDocumentPrincipal()
{
NS_ASSERTION(!mDocument || !mPrincipal,
"how'd we end up with both a document and a principal?");
if (mDocument) {
// If the document has a uri we'll ask for it's principal. Otherwise we'll
// consider this document 'anonymous'
if (!mDocument->GetDocumentURI()) {
return nsnull;
}
return mDocument->GetPrincipal();
}
return mPrincipal;
}
void
nsNodeInfoManager::SetDocumentPrincipal(nsIPrincipal *aPrincipal)
{
NS_ASSERTION(!mDocument,
"Don't set a principal, we already have a document.");
if (!mDocument) {
mPrincipal = aPrincipal;
}
NS_IF_RELEASE(mPrincipal);
NS_IF_ADDREF(mPrincipal = aPrincipal);
}
void

View File

@ -48,6 +48,12 @@ class nsINodeInfo;
class nsNodeInfo;
class nsIPrincipal;
class nsIURI;
class nsDocument;
class nsIDOMDocumentType;
class nsIDOMDocument;
class nsAString;
class nsIDOMNamedNodeMap;
class nsXULPrototypeDocument;
class nsNodeInfoManager
{
@ -105,18 +111,32 @@ public:
}
/**
* Gets the principal of the document associated with this.
* Gets the principal of the document this nodeinfo manager belongs to.
*/
nsIPrincipal *GetDocumentPrincipal();
/**
* Sets the principal of the nodeinfo manager. This should only be called
* when this nodeinfo manager isn't connected to an nsIDocument.
*/
void SetDocumentPrincipal(nsIPrincipal *aPrincipal);
nsIPrincipal *GetDocumentPrincipal() const {
return mPrincipal;
}
void RemoveNodeInfo(nsNodeInfo *aNodeInfo);
protected:
friend class nsDocument;
friend class nsXULPrototypeDocument;
friend nsresult (::NS_NewDOMDocumentType(nsIDOMDocumentType** ,
nsNodeInfoManager *,
nsIPrincipal *,
nsIAtom *,
nsIDOMNamedNodeMap *,
nsIDOMNamedNodeMap *,
const nsAString& ,
const nsAString& ,
const nsAString& ));
/**
* Sets the principal of the document this nodeinfo manager belongs to.
*/
void SetDocumentPrincipal(nsIPrincipal *aPrincipal);
private:
static PRIntn PR_CALLBACK NodeInfoInnerKeyCompare(const void *key1,
const void *key2);
@ -127,7 +147,8 @@ private:
PLHashTable *mNodeInfoHash;
nsIDocument *mDocument; // WEAK
nsCOMPtr<nsIPrincipal> mPrincipal;
nsIPrincipal *mPrincipal; // STRONG, but not nsCOMPtr to avoid include hell
// while inlining of GetPrincipal()
nsINodeInfo *mTextNodeInfo; // WEAK to avoid circular ownership
nsINodeInfo *mCommentNodeInfo; // WEAK to avoid circular ownership
nsINodeInfo *mDocumentNodeInfo; // WEAK to avoid circular ownership

View File

@ -810,7 +810,9 @@ nsObjectLoadingContent::LoadObject(nsIURI* aURI,
if (aURI) {
nsIScriptSecurityManager* secMan = nsContentUtils::GetSecurityManager();
NS_ASSERTION(secMan, "No security manager!?");
nsresult rv = secMan->CheckLoadURIWithPrincipal(doc->GetPrincipal(), aURI, 0);
nsresult rv =
secMan->CheckLoadURIWithPrincipal(thisContent->GetNodePrincipal(),
aURI, 0);
if (NS_FAILED(rv)) {
Fallback(PR_FALSE);
return NS_OK;

View File

@ -500,7 +500,7 @@ nsScriptLoader::DoProcessScriptElement(nsIScriptElement *aElement,
nsCOMPtr<nsIURI> scriptURI = aElement->GetScriptURI();
if (scriptURI) {
// Check that the containing page is allowed to load this URI.
nsIPrincipal *docPrincipal = mDocument->GetPrincipal();
nsIPrincipal *docPrincipal = mDocument->GetNodePrincipal();
NS_ENSURE_TRUE(docPrincipal, NS_ERROR_UNEXPECTED);
rv = nsContentUtils::GetSecurityManager()->
CheckLoadURIWithPrincipal(docPrincipal, scriptURI,
@ -715,7 +715,7 @@ nsScriptLoader::EvaluateScript(nsScriptLoadRequest* aRequest,
return NS_ERROR_FAILURE;
}
nsIPrincipal *principal = mDocument->GetPrincipal();
nsIPrincipal *principal = mDocument->GetNodePrincipal();
// We can survive without a principal, but we really should
// have one.
NS_ASSERTION(principal, "principal required for document");
@ -986,7 +986,7 @@ nsScriptLoader::OnStreamComplete(nsIStreamLoader* aLoader,
nsCOMPtr<nsIPrincipal> principal = do_QueryInterface(owner);
if (principal) {
nsIPrincipal *docPrincipal = mDocument->GetPrincipal();
nsIPrincipal *docPrincipal = mDocument->GetNodePrincipal();
if (docPrincipal) {
nsCOMPtr<nsIPrincipal> newPrincipal =
IntersectPrincipalCerts(docPrincipal, principal);

View File

@ -1587,13 +1587,12 @@ nsGenericHTMLElement::HandleDOMEventForAnchors(nsPresContext* aPresContext,
case NS_UI_ACTIVATE:
if (nsEventStatus_eConsumeNoDefault != *aEventStatus) {
nsAutoString target;
nsCOMPtr<nsIURI> baseURI = GetBaseURI();
GetAttr(kNameSpaceID_None, nsHTMLAtoms::target, target);
if (target.IsEmpty()) {
GetBaseTarget(target);
}
ret = TriggerLink(aPresContext, eLinkVerb_Replace, baseURI, hrefURI,
ret = TriggerLink(aPresContext, eLinkVerb_Replace, hrefURI,
target, PR_TRUE, PR_TRUE);
}
break;
@ -1617,12 +1616,11 @@ nsGenericHTMLElement::HandleDOMEventForAnchors(nsPresContext* aPresContext,
case NS_FOCUS_CONTENT:
{
nsAutoString target;
nsCOMPtr<nsIURI> baseURI = GetBaseURI();
GetAttr(kNameSpaceID_None, nsHTMLAtoms::target, target);
if (target.IsEmpty()) {
GetBaseTarget(target);
}
ret = TriggerLink(aPresContext, eLinkVerb_Replace, baseURI,
ret = TriggerLink(aPresContext, eLinkVerb_Replace,
hrefURI, target, PR_FALSE, PR_TRUE);
}
break;

View File

@ -1410,7 +1410,7 @@ nsHTMLFormElement::GetActionURL(nsIURI** aActionURL)
nsIScriptSecurityManager *securityManager =
nsContentUtils::GetSecurityManager();
rv = securityManager->
CheckLoadURIWithPrincipal(document->GetPrincipal(), actionURL,
CheckLoadURIWithPrincipal(GetNodePrincipal(), actionURL,
nsIScriptSecurityManager::STANDARD);
NS_ENSURE_SUCCESS(rv, rv);

View File

@ -1991,7 +1991,7 @@ IsScriptEnabled(nsIDocument *aDoc, nsIDocShell *aContainer)
{
NS_ENSURE_TRUE(aDoc && aContainer, PR_TRUE);
nsIPrincipal *principal = aDoc->GetPrincipal();
nsIPrincipal *principal = aDoc->GetNodePrincipal();
NS_ENSURE_TRUE(principal, PR_TRUE);
nsCOMPtr<nsIScriptGlobalObject> globalObject = aDoc->GetScriptGlobalObject();
@ -3611,7 +3611,7 @@ HTMLContentSink::ProcessBASEElement(nsGenericHTMLElement* aElement)
nsContentUtils::GetSecurityManager();
rv = securityManager->
CheckLoadURIWithPrincipal(mDocument->GetPrincipal(), baseHrefURI,
CheckLoadURIWithPrincipal(mDocument->GetNodePrincipal(), baseHrefURI,
nsIScriptSecurityManager::STANDARD);
if (NS_SUCCEEDED(rv)) {
mBaseHref = baseHrefURI;

View File

@ -1511,7 +1511,7 @@ nsHTMLDocument::GetDomainURI(nsIURI **aURI)
{
*aURI = nsnull;
nsIPrincipal *principal = GetPrincipal();
nsIPrincipal *principal = GetNodePrincipal();
if (!principal)
return;
@ -1594,11 +1594,15 @@ nsHTMLDocument::SetDomain(const nsAString& aDomain)
if (NS_FAILED(NS_NewURI(getter_AddRefs(newURI), newURIString)))
return NS_ERROR_FAILURE;
nsresult rv = mPrincipal->SetDomain(newURI);
nsresult rv = NS_ERROR_NOT_AVAILABLE;
nsIPrincipal* principal = GetNodePrincipal();
if (principal) {
rv = principal->SetDomain(newURI);
// Bug 13871: Frameset spoofing - note that document.domain was set
if (NS_SUCCEEDED(rv)) {
mDomainWasSet = PR_TRUE;
// Bug 13871: Frameset spoofing - note that document.domain was set
if (NS_SUCCEEDED(rv)) {
mDomainWasSet = PR_TRUE;
}
}
return rv;
@ -1820,7 +1824,10 @@ nsHTMLDocument::GetCookie(nsAString& aCookie)
// Get a URI from the document principal. We use the original
// codebase in case the codebase was changed by SetDomain
nsCOMPtr<nsIURI> codebaseURI;
mPrincipal->GetURI(getter_AddRefs(codebaseURI));
nsIPrincipal* principal = GetNodePrincipal();
if (principal) {
principal->GetURI(getter_AddRefs(codebaseURI));
}
if (!codebaseURI) {
// Document's principal is not a codebase (may be system), so
@ -1850,7 +1857,10 @@ nsHTMLDocument::SetCookie(const nsAString& aCookie)
}
nsCOMPtr<nsIURI> codebaseURI;
mPrincipal->GetURI(getter_AddRefs(codebaseURI));
nsIPrincipal* principal = GetNodePrincipal();
if (principal) {
principal->GetURI(getter_AddRefs(codebaseURI));
}
if (!codebaseURI) {
// Document's principal is not a codebase (may be system), so
@ -1947,6 +1957,11 @@ nsHTMLDocument::OpenCommon(const nsACString& aContentType, PRBool aReplace)
return rv;
}
// Set the caller principal, if any, on the channel so that we'll
// make sure to use it when we reset.
rv = channel->SetOwner(callerPrincipal);
NS_ENSURE_SUCCESS(rv, rv);
// Before we reset the doc notify the globalwindow of the change,
// but only if we still have a window (i.e. our window object the
// current inner window in our outer window).
@ -2010,9 +2025,9 @@ nsHTMLDocument::OpenCommon(const nsACString& aContentType, PRBool aReplace)
// Put the root element back into the document, we don't notify
// the document about this insertion since the sink will do that
// for us, the sink will call InitialReflow() and that'll create
// frames for the root element and the scrollbars work as expected
// (since the document in the root element was never set to null)
// for us and that'll create frames for the root element and the
// scrollbars work as expected (since the document in the root
// element was never set to null)
mChildren.AppendChild(root);
mRootContent = root;
@ -2039,17 +2054,6 @@ nsHTMLDocument::OpenCommon(const nsACString& aContentType, PRBool aReplace)
// resetting the document.
mSecurityInfo = securityInfo;
// Restore the principal to that of the caller.
mPrincipal = callerPrincipal;
// Recover if we had a problem obtaining the caller principal. In
// such a case we set the documents URI to be about:blank (uri is
// set to that above already) and the appropriate principal will be
// created as needed.
if (!mPrincipal) {
mDocumentURI = uri;
}
mParser = do_CreateInstance(kCParserCID, &rv);
// This will be propagated to the parser when someone actually calls write()
@ -2310,7 +2314,7 @@ nsHTMLDocument::ScriptWriteCommon(PRBool aNewlineTerminate)
if (subjectURI) {
mDocumentURI = subjectURI;
mPrincipal = subject;
SetPrincipal(subject);
}
}
}

View File

@ -1222,7 +1222,7 @@ nsXBLBinding::AllowScripts()
nsCOMPtr<nsIDocument> ourDocument;
mPrototypeBinding->XBLDocumentInfo()->GetDocument(getter_AddRefs(ourDocument));
nsIPrincipal* principal = ourDocument->GetPrincipal();
nsIPrincipal* principal = ourDocument->GetNodePrincipal();
if (!principal) {
return PR_FALSE;
}

View File

@ -725,7 +725,7 @@ nsXBLContentSink::ConstructImplementation(const PRUnichar **aAtts)
// our XBL document has UniversalXPConnect privileges. No principal
// means no privs!
nsIPrincipal* principal = mDocument->GetPrincipal();
nsIPrincipal* principal = mDocument->GetNodePrincipal();
if (principal) {
// XXX this api is so badly tied to JS it's not even funny. We don't
// have a concept of enabling capabilities on a per-principal basis,

View File

@ -343,7 +343,7 @@ nsXBLDocGlobalObject::GetPrincipal()
rv = docInfo->GetDocument(getter_AddRefs(document));
NS_ENSURE_SUCCESS(rv, nsnull);
return document->GetPrincipal();
return document->GetNodePrincipal();
}
static PRBool IsChromeURI(nsIURI* aURI)

View File

@ -554,7 +554,7 @@ nsXBLService::LoadBindings(nsIContent* aContent, nsIURI* aURL, PRBool aAugmentFl
nsIScriptSecurityManager *secMan = nsContentUtils::GetSecurityManager();
rv = secMan->
CheckLoadURIWithPrincipal(document->GetPrincipal(), aURL,
CheckLoadURIWithPrincipal(document->GetNodePrincipal(), aURL,
nsIScriptSecurityManager::ALLOW_CHROME);
if (NS_FAILED(rv))
return rv;

View File

@ -242,29 +242,18 @@ nsXMLElement::MaybeTriggerAutoLink(nsIDocShell *aShell)
break;
}
// base
nsCOMPtr<nsIURI> base = GetBaseURI();
if (!base)
// Get our URI
nsCOMPtr<nsIURI> uri = nsContentUtils::GetXLinkURI(this);
if (!uri)
break;
// href= ?
if (GetAttr(kNameSpaceID_XLink, nsHTMLAtoms::href, value)) {
nsCOMPtr<nsIURI> uri;
rv = nsContentUtils::NewURIWithDocumentCharset(getter_AddRefs(uri),
value,
GetOwnerDoc(),
base);
if (NS_SUCCEEDED(rv)) {
nsCOMPtr<nsPresContext> pc;
rv = DocShellToPresContext(aShell, getter_AddRefs(pc));
if (NS_SUCCEEDED(rv)) {
rv = TriggerLink(pc, verb, base, uri,
EmptyString(), PR_TRUE, PR_FALSE);
nsCOMPtr<nsPresContext> pc;
rv = DocShellToPresContext(aShell, getter_AddRefs(pc));
if (NS_SUCCEEDED(rv)) {
rv = TriggerLink(pc, verb, uri, EmptyString(), PR_TRUE, PR_FALSE);
return SpecialAutoLoadReturn(rv,verb);
}
}
} // href
return SpecialAutoLoadReturn(rv,verb);
}
}
} while (0);
}
@ -331,8 +320,7 @@ nsXMLElement::HandleDOMEvent(nsPresContext* aPresContext,
nsAutoString target;
GetAttr(kNameSpaceID_XLink, nsLayoutAtoms::_moz_target, target);
nsCOMPtr<nsIURI> baseURI = GetBaseURI();
ret = TriggerLink(aPresContext, verb, baseURI, uri,
ret = TriggerLink(aPresContext, verb, uri,
target, PR_TRUE, PR_TRUE);
*aEventStatus = nsEventStatus_eConsumeDoDefault;
@ -373,24 +361,14 @@ nsXMLElement::HandleDOMEvent(nsPresContext* aPresContext,
case NS_MOUSE_ENTER_SYNTH:
{
nsAutoString href;
GetAttr(kNameSpaceID_XLink, nsHTMLAtoms::href, href);
if (href.IsEmpty()) {
nsCOMPtr<nsIURI> uri = nsContentUtils::GetXLinkURI(this);
if (!uri) {
*aEventStatus = nsEventStatus_eConsumeDoDefault;
break;
}
nsCOMPtr<nsIURI> baseURI = GetBaseURI();
nsCOMPtr<nsIURI> uri;
ret = nsContentUtils::NewURIWithDocumentCharset(getter_AddRefs(uri),
href,
document,
baseURI);
if (NS_SUCCEEDED(ret)) {
ret = TriggerLink(aPresContext, eLinkVerb_Replace, baseURI, uri,
EmptyString(), PR_FALSE, PR_TRUE);
}
ret = TriggerLink(aPresContext, eLinkVerb_Replace, uri,
EmptyString(), PR_FALSE, PR_TRUE);
*aEventStatus = nsEventStatus_eConsumeDoDefault;
}

View File

@ -598,7 +598,8 @@ nsXMLContentSink::LoadXSLStyleSheet(nsIURI* aUrl)
return NS_ERROR_FAILURE;
}
return mXSLTProcessor->LoadStyleSheet(aUrl, loadGroup, mDocument->GetPrincipal());
return mXSLTProcessor->LoadStyleSheet(aUrl, loadGroup,
mDocument->GetNodePrincipal());
}
nsresult
@ -637,7 +638,7 @@ nsXMLContentSink::ProcessStyleLink(nsIContent* aElement,
// Do security check
nsIScriptSecurityManager *secMan = nsContentUtils::GetSecurityManager();
rv = secMan->
CheckLoadURIWithPrincipal(mDocument->GetPrincipal(), url,
CheckLoadURIWithPrincipal(mDocument->GetNodePrincipal(), url,
nsIScriptSecurityManager::ALLOW_CHROME);
NS_ENSURE_SUCCESS(rv, NS_OK);

View File

@ -297,7 +297,14 @@ nsXMLDocument::OnChannelRedirect(nsIChannel *aOldChannel,
return rv;
}
return secMan->GetCodebasePrincipal(newLocation, getter_AddRefs(mPrincipal));
// XXXbz Shouldn't we look at the owner on the new channel at some point?
// It's not gonna be right here, but eventually it will....
nsCOMPtr<nsIPrincipal> principal;
rv = secMan->GetCodebasePrincipal(newLocation, getter_AddRefs(principal));
NS_ENSURE_SUCCESS(rv, rv);
SetPrincipal(principal);
return NS_OK;
}
NS_IMETHODIMP
@ -410,12 +417,12 @@ nsXMLDocument::Load(const nsAString& aUrl, PRBool *aReturn)
// remain. This should be done before the security check is done to
// ensure that the document is reset even if the new document can't
// be loaded.
nsCOMPtr<nsIPrincipal> principal(mPrincipal);
nsCOMPtr<nsIPrincipal> principal = GetNodePrincipal();
nsCOMPtr<nsIEventListenerManager> elm(mListenerManager);
ResetToURI(uri, nsnull);
mPrincipal = principal;
SetPrincipal(principal);
mListenerManager = elm;
// Get security manager, check to see if we're allowed to load this URI
@ -467,19 +474,22 @@ nsXMLDocument::Load(const nsAString& aUrl, PRBool *aReturn)
}
// Set a principal for this document
// XXXbz StartDocumentLoad should handle that.... And we shouldn't be calling
// StartDocumentLoad until we get an OnStartRequest from this channel!
nsCOMPtr<nsISupports> channelOwner;
rv = channel->GetOwner(getter_AddRefs(channelOwner));
// We don't care if GetOwner() succeeded here, if it failed,
// channelOwner will be null, which is what we want in that case.
principal = do_QueryInterface(channelOwner);
mPrincipal = do_QueryInterface(channelOwner);
if (NS_FAILED(rv) || !mPrincipal) {
rv = secMan->GetCodebasePrincipal(uri, getter_AddRefs(mPrincipal));
NS_ENSURE_TRUE(mPrincipal, rv);
if (NS_FAILED(rv) || !principal) {
rv = secMan->GetCodebasePrincipal(uri, getter_AddRefs(principal));
NS_ENSURE_TRUE(principal, rv);
}
SetPrincipal(principal);
nsCOMPtr<nsIEventQueue> modalEventQueue;
if(!mAsync) {

View File

@ -206,26 +206,22 @@ void URIUtils::resolveHref(const nsAString& href, const nsAString& base,
void
URIUtils::ResetWithSource(nsIDocument *aNewDoc, nsIDOMNode *aSourceNode)
{
if (!aSourceNode) {
nsCOMPtr<nsINode> node = do_QueryInterface(aSourceNode);
if (!node) {
// XXXbz passing nsnull as the first arg to Reset is illegal
aNewDoc->Reset(nsnull, nsnull);
return;
}
nsCOMPtr<nsIDocument> sourceDoc = do_QueryInterface(aSourceNode);
nsCOMPtr<nsIDocument> sourceDoc = node->GetOwnerDoc();
if (!sourceDoc) {
nsCOMPtr<nsIDOMDocument> sourceDOMDocument;
aSourceNode->GetOwnerDocument(getter_AddRefs(sourceDOMDocument));
sourceDoc = do_QueryInterface(sourceDOMDocument);
}
if (!sourceDoc) {
NS_ASSERTION(0, "no source document found");
NS_ERROR("no source document found");
// XXXbz passing nsnull as the first arg to Reset is illegal
aNewDoc->Reset(nsnull, nsnull);
return;
}
nsIPrincipal* sourcePrincipal = sourceDoc->GetPrincipal();
nsIPrincipal* sourcePrincipal = sourceDoc->GetNodePrincipal();
if (!sourcePrincipal) {
return;
}

View File

@ -174,7 +174,7 @@ void txMozillaTextOutput::createResultDocument(nsIDOMDocument* aSourceDocument,
// Reset and set up document
nsCOMPtr<nsIDocument> sourceDoc = do_QueryInterface(aSourceDocument);
nsIPrincipal* sourcePrincipal = sourceDoc->GetPrincipal();
nsIPrincipal* sourcePrincipal = sourceDoc->GetNodePrincipal();
if (!sourcePrincipal) {
return;
}

View File

@ -3328,7 +3328,7 @@ nsXULPrototypeScript::Compile(const PRUnichar* aText,
// Use the enclosing document's principal
// XXX is this right? or should we use the protodoc's?
nsIPrincipal *principal = aDocument->GetPrincipal();
nsIPrincipal *principal = aDocument->GetNodePrincipal();
if (!principal)
return NS_ERROR_FAILURE;

View File

@ -238,12 +238,10 @@ XULPopupListenerImpl::PreLaunchPopup(nsIDOMEvent* aMouseEvent)
// The user wants his contextmenus. Let's make sure that this is a website
// and not chrome since there could be places in chrome which don't want
// contextmenus.
nsCOMPtr<nsIDocument> doc;
nsCOMPtr<nsIPrincipal> prin;
nsContentUtils::GetDocumentAndPrincipal(targetNode,
getter_AddRefs(doc),
getter_AddRefs(prin));
if (prin) {
nsCOMPtr<nsINode> node = do_QueryInterface(targetNode);
if (node) {
nsIPrincipal* prin = node->GetNodePrincipal();
nsIScriptSecurityManager *securityManager =
nsContentUtils::GetSecurityManager();

View File

@ -1282,7 +1282,7 @@ XULContentSinkImpl::OpenScript(const PRUnichar** aAttributes,
if (NS_SUCCEEDED(rv)) {
rv = mSecMan->
CheckLoadURIWithPrincipal(doc->GetPrincipal(),
CheckLoadURIWithPrincipal(doc->GetNodePrincipal(),
script->mSrcURI,
nsIScriptSecurityManager::ALLOW_CHROME);
}

View File

@ -364,14 +364,6 @@ nsXULDocument::~nsXULDocument()
mStyleAttrStyleSheet = nsnull;
mAttrStyleSheet = nsnull;
}
// This is done in nsDocument::~nsDocument() too, but since this
// call ends up calling back into the document through virtual
// methods (nsIDocument::GetPrincipal()) we must do it here before
// we go out of nsXULDocument's destructor.
if (mNodeInfoManager) {
mNodeInfoManager->DropDocumentReference();
}
}
nsresult
@ -521,6 +513,9 @@ nsXULDocument::StartDocumentLoad(const char* aCommand, nsIChannel* aChannel,
mMasterPrototype = mCurrentPrototype = proto;
// Set up the right principal on ourselves.
SetPrincipal(proto->GetDocumentPrincipal());
// Add cloned style sheet references only if the prototype has in
// fact already loaded. It may still be loading when we hit the XUL
// prototype cache.
@ -578,22 +573,6 @@ nsXULDocument::StartDocumentLoad(const char* aCommand, nsIChannel* aChannel,
return NS_OK;
}
nsIPrincipal*
nsXULDocument::GetPrincipal()
{
NS_ASSERTION(mMasterPrototype, "Missing master prototype. See bug 169036");
NS_ENSURE_TRUE(mMasterPrototype, nsnull);
return mMasterPrototype->GetDocumentPrincipal();
}
void
nsXULDocument::SetPrincipal(nsIPrincipal *aPrincipal)
{
NS_NOTREACHED("SetPrincipal");
}
void
nsXULDocument::EndLoad()
{
@ -2102,14 +2081,22 @@ nsXULDocument::PrepareToLoadPrototype(nsIURI* aURI, const char* aCommand,
if (NS_FAILED(rv)) return rv;
// Bootstrap the master document prototype.
PRBool isMasterProto = PR_FALSE;
if (! mMasterPrototype) {
mMasterPrototype = mCurrentPrototype;
mMasterPrototype->SetDocumentPrincipal(aDocumentPrincipal);
isMasterProto = PR_TRUE;
}
rv = mCurrentPrototype->SetURI(aURI);
if (NS_FAILED(rv)) return rv;
if (isMasterProto) {
// Set our principal based on the master proto. Note that this MUST
// come after the SetURI and SetDocumentPrincipal calls above.
SetPrincipal(mMasterPrototype->GetDocumentPrincipal());
}
// Create a XUL content sink, a parser, and kick off a load for
// the overlay.
nsCOMPtr<nsIXULContentSink> sink;

View File

@ -105,10 +105,6 @@ public:
PRBool aReset = PR_TRUE,
nsIContentSink* aSink = nsnull);
virtual nsIPrincipal* GetPrincipal();
virtual void SetPrincipal(nsIPrincipal *aPrincipal);
virtual void SetContentType(const nsAString& aContentType);
virtual void EndLoad();

View File

@ -706,10 +706,13 @@ nsXULTemplateBuilder::LoadDataSources(nsIDocument* doc)
mCompDB->SetAllowNegativeAssertions(PR_FALSE);
// Grab the doc's principal...
nsIPrincipal *docPrincipal = doc->GetPrincipal();
nsIPrincipal *docPrincipal = doc->GetNodePrincipal();
if (!docPrincipal)
return NS_ERROR_FAILURE;
NS_ASSERTION(docPrincipal == mRoot->GetNodePrincipal(),
"Principal mismatch? Which one to use?");
PRBool isTrusted = PR_FALSE;
rv = IsSystemPrincipal(docPrincipal, &isTrusted);
if (NS_FAILED(rv)) return rv;

View File

@ -785,18 +785,13 @@ nsXULTreeBuilder::SetTree(nsITreeBoxObject* tree)
if (! mBoxObject)
return NS_OK;
nsCOMPtr<nsIDocument> doc = mRoot->GetDocument();
NS_ASSERTION(doc, "element has no document");
if (!doc)
return NS_ERROR_UNEXPECTED;
// Grab the doc's principal...
nsIPrincipal* docPrincipal = doc->GetPrincipal();
if (!docPrincipal)
// Get our root's principal
nsIPrincipal* rootPrincipal = mRoot->GetNodePrincipal();
if (!rootPrincipal)
return NS_ERROR_FAILURE;
PRBool isTrusted = PR_FALSE;
nsresult rv = IsSystemPrincipal(docPrincipal, &isTrusted);
nsresult rv = IsSystemPrincipal(rootPrincipal, &isTrusted);
if (NS_SUCCEEDED(rv) && isTrusted) {
// Get the datasource we intend to use to remember open state.
nsAutoString datasourceStr;

View File

@ -1071,7 +1071,7 @@ nsDocShell::ValidateOrigin(nsIDocShellTreeItem* aOriginTreeItem,
nsCOMPtr<nsIDocument> targetDocument(do_QueryInterface(targetDOMDocument));
NS_ENSURE_TRUE(targetDocument, PR_TRUE);
nsIPrincipal *targetPrincipal = targetDocument->GetPrincipal();
nsIPrincipal *targetPrincipal = targetDocument->GetNodePrincipal();
NS_ENSURE_TRUE(targetPrincipal, PR_TRUE);
nsCOMPtr<nsIURI> targetPrincipalURI;
@ -6725,7 +6725,7 @@ nsDocShell::GetCurrentDocumentOwner(nsISupports ** aOwner)
//-- Get the document's principal
if (document) {
*aOwner = document->GetPrincipal();
*aOwner = document->GetNodePrincipal();
}
NS_IF_ADDREF(*aOwner);

View File

@ -487,7 +487,7 @@ nsGlobalWindow::FreeInnerObjects(JSContext *cx)
NS_ASSERTION(mDoc, "Why is mDoc null?");
// Remember the document's principal.
mDocumentPrincipal = mDoc->GetPrincipal();
mDocumentPrincipal = mDoc->GetNodePrincipal();
}
// Remove our reference to the document and the document principal.
@ -640,6 +640,9 @@ nsGlobalWindow::WouldReuseInnerWindow(nsIDocument *aNewDocument, PRBool useDocUR
if (mOpenerScriptURL) {
if (sSecMan) {
PRBool isSameOrigin = PR_FALSE;
// XXXbz shouldn't we store the opener _principal_ and use
// CheckSameOriginPrincipal here instead? That would make a lot more
// sense to me...
sSecMan->SecurityCompareURIs(mOpenerScriptURL, newURI, &isSameOrigin);
if (isSameOrigin) {
// The origin is the same.
@ -954,14 +957,14 @@ nsGlobalWindow::SetNewDocument(nsIDocument* aDocument,
nsIPrincipal *oldPrincipal = nsnull;
if (oldDoc) {
oldPrincipal = oldDoc->GetPrincipal();
oldPrincipal = oldDoc->GetNodePrincipal();
}
// Drop our reference to the navigator object unless we're reusing
// the existing inner window or the new document is from the same
// origin as the old document.
if (!reUseInnerWindow && mNavigator && oldPrincipal) {
nsIPrincipal *newPrincipal = aDocument->GetPrincipal();
nsIPrincipal *newPrincipal = aDocument->GetNodePrincipal();
rv = NS_ERROR_FAILURE;
if (newPrincipal) {
@ -1346,7 +1349,7 @@ nsGlobalWindow::SetDocShell(nsIDocShell* aDocShell)
NS_ASSERTION(mDoc, "Must have doc!");
// Remember the document's principal.
mDocumentPrincipal = mDoc->GetPrincipal();
mDocumentPrincipal = mDoc->GetNodePrincipal();
// Release our document reference
mDocument = nsnull;
@ -1764,7 +1767,7 @@ nsGlobalWindow::GetPrincipal()
{
if (mDoc) {
// If we have a document, get the principal from the document
return mDoc->GetPrincipal();
return mDoc->GetNodePrincipal();
}
if (mDocumentPrincipal) {

View File

@ -115,6 +115,7 @@ public:
#include "nsIContent.h"
#include "nsIURI.h"
#include "nsIDocument.h"
#include "nsIScriptObjectPrincipal.h"
#include "nsIDOMWindow.h"
#include "nsIDOMElement.h"
#include "nsIDOMDocument.h"
@ -824,7 +825,7 @@ END_COM_MAP()
if (!scriptContext)
return E_UNEXPECTED;
nsCOMPtr<nsIDocument> doc(do_QueryInterface(domDocument));
nsCOMPtr<nsIScriptObjectPrincipal> doc(do_QueryInterface(domDocument));
if (!doc)
return E_UNEXPECTED;

View File

@ -1112,7 +1112,7 @@ nsXFormsUtils::CheckSameOrigin(nsIDocument *aBaseDocument, nsIURI *aTestURI)
nsresult rv;
// get the base document's principal
nsIPrincipal *basePrincipal = aBaseDocument->GetPrincipal();
nsIPrincipal *basePrincipal = aBaseDocument->GetNodePrincipal();
if (basePrincipal) {
// check for the UniversalBrowserRead capability.
@ -1123,19 +1123,18 @@ nsXFormsUtils::CheckSameOrigin(nsIDocument *aBaseDocument, nsIURI *aTestURI)
return PR_TRUE;
// check the security manager and do a same original check on the principal
nsCOMPtr<nsIScriptSecurityManager> secMan =
nsCOMPtr<nsIScriptSecurityManager> secMan =
do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID);
if (secMan) {
if (secMan) {
// get a principal for the uri we are testing
nsCOMPtr<nsIPrincipal> testPrincipal;
rv = secMan->GetCodebasePrincipal(aTestURI, getter_AddRefs(testPrincipal));
if (NS_SUCCEEDED(rv)) {
rv = secMan->CheckSameOriginPrincipal(aBaseDocument->GetPrincipal(),
testPrincipal);
if (NS_SUCCEEDED(rv))
return PR_TRUE;
}
rv = secMan->CheckSameOriginPrincipal(basePrincipal, testPrincipal);
if (NS_SUCCEEDED(rv))
return PR_TRUE;
}
}
}

View File

@ -39,7 +39,7 @@
#include "nsIDOMNode.h"
#include "nsIDOMClassInfo.h"
#include "nsIOutputStream.h"
#include "nsIContent.h"
#include "nsINode.h"
#include "nsIDocument.h"
#include "nsIDOMDocument.h"
#include "nsIDocumentEncoder.h"
@ -129,39 +129,21 @@ CheckSameOrigin(nsIDOMNode *aRoot)
{
// Make sure that the caller has permission to access the root
// Be sure to QI to either nsIContent or nsIDocument to make sure
// we're passed a naitve object.
// Be sure to QI to nsINode to make sure we're passed a native
// object.
nsCOMPtr<nsIContent> content(do_QueryInterface(aRoot));
nsCOMPtr<nsIDocument> doc;
nsCOMPtr<nsINode> node(do_QueryInterface(aRoot));
if (content) {
doc = content->GetOwnerDoc();
if (NS_UNLIKELY(!node)) {
// We got a non-native object.
if (!doc) {
// Orphan node, permit access.
return NS_OK;
}
} else {
doc = do_QueryInterface(aRoot);
if (!doc) {
// We got a non-native object.
return NS_ERROR_INVALID_POINTER;
}
return NS_ERROR_INVALID_POINTER;
}
nsCOMPtr<nsIURI> root_uri;
nsIPrincipal *principal = doc->GetPrincipal();
nsIPrincipal *principal = node->GetNodePrincipal();
if (principal) {
principal->GetURI(getter_AddRefs(root_uri));
}
if (root_uri) {
nsresult rv;
nsCOMPtr<nsIScriptSecurityManager> secMan =
do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv);
@ -177,9 +159,18 @@ CheckSameOrigin(nsIDOMNode *aRoot)
return NS_OK;
}
// Check if the caller (if any) is from the same origin that the
// root is from.
return secMan->CheckSameOrigin(nsnull, root_uri);
nsCOMPtr<nsIPrincipal> subject;
rv = secMan->GetSubjectPrincipal(getter_AddRefs(subject));
NS_ENSURE_SUCCESS(rv, rv);
// XXXbz can we happen to not have a subject principal here?
// nsScriptSecurityManager::IsCapabilityEnabled doesn't actually use
// GetSubjectPrincipal, so not sure...
// In any case, no subject principal means access is allowed.
if (subject) {
// Check if the caller is from the same origin that the root is from.
return secMan->CheckSameOriginPrincipal(subject, principal);
}
}
return NS_OK;

View File

@ -224,7 +224,7 @@ NS_IMETHODIMP mozLineTerm::GetSecurePrincipal(nsIDOMDocument *domDoc,
if (!doc)
return NS_ERROR_FAILURE;
nsIPrincipal *principal = doc->GetPrincipal();
nsIPrincipal *principal = doc->GetNodePrincipal();
if (!principal)
return NS_ERROR_FAILURE;

View File

@ -257,7 +257,7 @@ mozXMLTermUtils::ExecuteScript(nsIDOMDocument* aDOMDocument,
if (!doc)
return NS_ERROR_FAILURE;
nsIPrincipal *docPrincipal = doc->GetPrincipal();
nsIPrincipal *docPrincipal = doc->GetNodePrincipal();
if (!docPrincipal)
return NS_ERROR_FAILURE;

View File

@ -1512,13 +1512,16 @@ void
nsImageFrame::TriggerLink(nsPresContext* aPresContext,
nsIURI* aURI,
const nsString& aTargetSpec,
nsINode* aTriggerNode,
PRBool aClick)
{
NS_PRECONDITION(aTriggerNode, "Must have triggering node");
// We get here with server side image map
nsILinkHandler *handler = aPresContext->GetLinkHandler();
if (handler) {
if (aClick) {
// Check that this page is allowed to load this URI.
// Check that the triggering node is allowed to load this URI.
// Almost a copy of the similarly named method in nsGenericElement
nsresult rv;
nsCOMPtr<nsIScriptSecurityManager> securityManager =
@ -1527,22 +1530,20 @@ nsImageFrame::TriggerLink(nsPresContext* aPresContext,
if (NS_FAILED(rv))
return;
nsIPresShell *ps = aPresContext->GetPresShell();
if (!ps)
nsIPrincipal* principal = aTriggerNode->GetNodePrincipal();
if (!principal) {
return;
nsIDocument *doc = ps->GetDocument();
if (doc) {
rv = securityManager->
CheckLoadURIWithPrincipal(doc->GetPrincipal(), aURI,
nsIScriptSecurityManager::STANDARD);
// Only pass off the click event if the script security manager
// says it's ok.
if (NS_SUCCEEDED(rv))
handler->OnLinkClick(mContent, eLinkVerb_Replace, aURI,
aTargetSpec.get());
}
rv = securityManager->
CheckLoadURIWithPrincipal(principal, aURI,
nsIScriptSecurityManager::STANDARD);
// Only pass off the click event if the script security manager
// says it's ok.
if (NS_SUCCEEDED(rv))
handler->OnLinkClick(mContent, eLinkVerb_Replace, aURI,
aTargetSpec.get());
}
else {
handler->OnOverLink(mContent, aURI, aTargetSpec.get());
@ -1580,10 +1581,13 @@ nsImageFrame::TranslateEventCoords(const nsPoint& aPoint,
}
PRBool
nsImageFrame::GetAnchorHREFAndTarget(nsIURI** aHref, nsString& aTarget)
nsImageFrame::GetAnchorHREFTargetAndNode(nsIURI** aHref, nsString& aTarget,
nsINode** aNode)
{
PRBool status = PR_FALSE;
aTarget.Truncate();
*aHref = nsnull;
*aNode = nsnull;
// Walk up the content tree, looking for an nsIDOMAnchorElement
for (nsIContent* content = mContent->GetParent();
@ -1597,6 +1601,7 @@ nsImageFrame::GetAnchorHREFAndTarget(nsIURI** aHref, nsString& aTarget)
if (anchor) {
anchor->GetTarget(aTarget);
}
NS_ADDREF(*aNode = content);
break;
}
}
@ -1680,7 +1685,9 @@ nsImageFrame::HandleEvent(nsPresContext* aPresContext,
// element to provide the basis for the destination url.
nsCOMPtr<nsIURI> uri;
nsAutoString target;
if (GetAnchorHREFAndTarget(getter_AddRefs(uri), target)) {
nsCOMPtr<nsINode> anchorNode;
if (GetAnchorHREFTargetAndNode(getter_AddRefs(uri), target,
getter_AddRefs(anchorNode))) {
// XXX if the mouse is over/clicked in the border/padding area
// we should probably just pretend nothing happened. Nav4
// keeps the x,y coordinates positive as we do; IE doesn't
@ -1698,7 +1705,7 @@ nsImageFrame::HandleEvent(nsPresContext* aPresContext,
*aEventStatus = nsEventStatus_eConsumeDoDefault;
clicked = PR_TRUE;
}
TriggerLink(aPresContext, uri, target, clicked);
TriggerLink(aPresContext, uri, target, anchorNode, clicked);
}
}
}

View File

@ -170,6 +170,7 @@ protected:
void TriggerLink(nsPresContext* aPresContext,
nsIURI* aURI,
const nsString& aTargetSpec,
nsINode* aTriggerNode,
PRBool aClick);
PRBool IsServerImageMap();
@ -177,7 +178,8 @@ protected:
void TranslateEventCoords(const nsPoint& aPoint,
nsPoint& aResult);
PRBool GetAnchorHREFAndTarget(nsIURI** aHref, nsString& aTarget);
PRBool GetAnchorHREFTargetAndNode(nsIURI** aHref, nsString& aTarget,
nsINode** aNode);
void MeasureString(const PRUnichar* aString,
PRInt32 aLength,

View File

@ -3385,7 +3385,7 @@ NS_IMETHODIMP nsPluginHostImpl::InstantiateEmbeddedPlugin(const char *aMimeType,
if (!doc)
return NS_ERROR_NULL_POINTER;
rv = secMan->CheckLoadURIWithPrincipal(doc->GetPrincipal(), aURL, 0);
rv = secMan->CheckLoadURIWithPrincipal(doc->GetNodePrincipal(), aURL, 0);
if (NS_FAILED(rv))
return rv;
@ -5758,7 +5758,7 @@ NS_IMETHODIMP nsPluginHostImpl::NewPluginURLStream(const nsString& aURL,
if (doc)
{
// Set the owner of channel to the document principal...
channel->SetOwner(doc->GetPrincipal());
channel->SetOwner(doc->GetNodePrincipal());
}
// deal with headers and post data
@ -5840,7 +5840,7 @@ nsPluginHostImpl::DoURLLoadSecurityCheck(nsIPluginInstance *aInstance,
if (NS_FAILED(rv))
return rv;
return secMan->CheckLoadURIWithPrincipal(doc->GetPrincipal(), targetURL,
return secMan->CheckLoadURIWithPrincipal(doc->GetNodePrincipal(), targetURL,
nsIScriptSecurityManager::STANDARD);
}

View File

@ -61,9 +61,9 @@
#include "nsIURIFixup.h"
#include "nsCDefaultURIFixup.h"
// Needed for nsIDocument::FlushPendingNotifications(...)
#include "nsIDOMDocument.h"
#include "nsIDocument.h"
#include "nsIScriptObjectPrincipal.h"
#include "nsIURI.h"
// CIDs
static NS_DEFINE_CID(kWindowMediatorCID, NS_WINDOWMEDIATOR_CID);
@ -625,7 +625,7 @@ NS_IMETHODIMP nsContentTreeOwner::SetTitle(const PRUnichar* aTitle)
nsCOMPtr<nsIDocShellTreeItem> dsitem;
GetPrimaryContentShell(getter_AddRefs(dsitem));
nsCOMPtr<nsIDOMDocument> domdoc(do_GetInterface(dsitem));
nsCOMPtr<nsIDocument> doc(do_QueryInterface(domdoc));
nsCOMPtr<nsIScriptObjectPrincipal> doc(do_QueryInterface(domdoc));
if (doc) {
nsCOMPtr<nsIURI> uri;
nsIPrincipal* principal = doc->GetPrincipal();