From 263cf7dc110e2218e24d5edc9bc3d11c73a1b7fc Mon Sep 17 00:00:00 2001 From: "bzbarsky%mit.edu" Date: Thu, 2 Feb 2006 20:02:34 +0000 Subject: [PATCH] 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 --- content/base/public/nsContentUtils.h | 4 - content/base/public/nsIAttribute.h | 4 +- content/base/public/nsIContent.h | 6 +- content/base/public/nsIDocument.h | 11 +- content/base/public/nsINode.h | 16 +- content/base/src/nsContentAreaDragDrop.cpp | 4 +- content/base/src/nsContentSink.cpp | 2 +- content/base/src/nsContentUtils.cpp | 182 +++--------------- content/base/src/nsDocument.cpp | 51 +++-- content/base/src/nsDocument.h | 9 +- content/base/src/nsFrameLoader.cpp | 4 +- content/base/src/nsGenericElement.cpp | 10 +- content/base/src/nsGenericElement.h | 7 +- content/base/src/nsNodeInfoManager.cpp | 43 +---- content/base/src/nsNodeInfoManager.h | 39 +++- content/base/src/nsObjectLoadingContent.cpp | 4 +- content/base/src/nsScriptLoader.cpp | 6 +- .../html/content/src/nsGenericHTMLElement.cpp | 6 +- .../html/content/src/nsHTMLFormElement.cpp | 2 +- .../html/document/src/nsHTMLContentSink.cpp | 4 +- content/html/document/src/nsHTMLDocument.cpp | 48 ++--- content/xbl/src/nsXBLBinding.cpp | 2 +- content/xbl/src/nsXBLContentSink.cpp | 2 +- content/xbl/src/nsXBLDocumentInfo.cpp | 2 +- content/xbl/src/nsXBLService.cpp | 2 +- content/xml/content/src/nsXMLElement.cpp | 50 ++--- content/xml/document/src/nsXMLContentSink.cpp | 5 +- content/xml/document/src/nsXMLDocument.cpp | 26 ++- content/xslt/src/base/txURIUtils.cpp | 14 +- content/xslt/src/xslt/txMozillaTextOutput.cpp | 2 +- content/xul/content/src/nsXULElement.cpp | 2 +- .../xul/content/src/nsXULPopupListener.cpp | 10 +- content/xul/document/src/nsXULContentSink.cpp | 2 +- content/xul/document/src/nsXULDocument.cpp | 35 ++-- content/xul/document/src/nsXULDocument.h | 4 - .../templates/src/nsXULTemplateBuilder.cpp | 5 +- .../xul/templates/src/nsXULTreeBuilder.cpp | 13 +- docshell/base/nsDocShell.cpp | 4 +- dom/src/base/nsGlobalWindow.cpp | 13 +- .../activex/src/plugin/XPCDocument.cpp | 3 +- extensions/xforms/nsXFormsUtils.cpp | 15 +- .../xmlextras/base/src/nsDOMSerializer.cpp | 51 ++--- extensions/xmlterm/base/mozLineTerm.cpp | 2 +- extensions/xmlterm/base/mozXMLTermUtils.cpp | 2 +- layout/generic/nsImageFrame.cpp | 43 +++-- layout/generic/nsImageFrame.h | 4 +- modules/plugin/base/src/nsPluginHostImpl.cpp | 6 +- xpfe/appshell/src/nsContentTreeOwner.cpp | 6 +- 48 files changed, 308 insertions(+), 479 deletions(-) diff --git a/content/base/public/nsContentUtils.h b/content/base/public/nsContentUtils.h index 3e21c34d6c77..b17cec4fa098 100644 --- a/content/base/public/nsContentUtils.h +++ b/content/base/public/nsContentUtils.h @@ -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. diff --git a/content/base/public/nsIAttribute.h b/content/base/public/nsIAttribute.h index 88485b502814..6a78124ed112 100644 --- a/content/base/public/nsIAttribute.h +++ b/content/base/public/nsIAttribute.h @@ -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 { diff --git a/content/base/public/nsIContent.h b/content/base/public/nsIContent.h index 87fe62ab4f16..a4397b92efad 100644 --- a/content/base/public/nsIContent.h +++ b/content/base/public/nsIContent.h @@ -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 diff --git a/content/base/public/nsIDocument.h b/content/base/public/nsIDocument.h index 51d642f6a898..d080ea5f8e6b 100644 --- a/content/base/public/nsIDocument.h +++ b/content/base/public/nsIDocument.h @@ -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. */ diff --git a/content/base/public/nsINode.h b/content/base/public/nsINode.h index c9bf151a3a91..87ed5ddef4e3 100644 --- a/content/base/public/nsINode.h +++ b/content/base/public/nsINode.h @@ -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 diff --git a/content/base/src/nsContentAreaDragDrop.cpp b/content/base/src/nsContentAreaDragDrop.cpp index 34f9816b83a9..3a7d52740e55 100644 --- a/content/base/src/nsContentAreaDragDrop.cpp +++ b/content/base/src/nsContentAreaDragDrop.cpp @@ -563,9 +563,9 @@ nsContentAreaDragDrop::DragDrop(nsIDOMEvent* inMouseEvent) session->GetSourceDocument(getter_AddRefs(sourceDocument)); nsCOMPtr sourceDoc(do_QueryInterface(sourceDocument)); - if (sourceDoc && sourceDoc->GetPrincipal()) { + if (sourceDoc && sourceDoc->GetNodePrincipal()) { nsCOMPtr sourceUri; - sourceDoc->GetPrincipal()->GetURI(getter_AddRefs(sourceUri)); + sourceDoc->GetNodePrincipal()->GetURI(getter_AddRefs(sourceUri)); if (sourceUri) { nsCAutoString sourceUriStr; diff --git a/content/base/src/nsContentSink.cpp b/content/base/src/nsContentSink.cpp index 75840372918e..7a3280e90cef 100644 --- a/content/base/src/nsContentSink.cpp +++ b/content/base/src/nsContentSink.cpp @@ -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; } diff --git a/content/base/src/nsContentUtils.cpp b/content/base/src/nsContentUtils.cpp index 9cae9b12026c..0426525f835b 100644 --- a/content/base/src/nsContentUtils.cpp +++ b/content/base/src/nsContentUtils.cpp @@ -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 content = do_QueryInterface(aNode); - nsCOMPtr 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 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 trustedNode = do_QueryInterface(aTrustedNode); + nsCOMPtr unTrustedNode = do_QueryInterface(aUnTrustedNode); - // In most cases this is a document, so lets try that first - nsCOMPtr 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 trustCont = do_QueryInterface(aTrustedNode); - NS_ASSERTION(trustCont, - "aTrustedNode is neither nsIContent nor nsIDocument!"); -#endif - nsCOMPtr 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 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 unTrustedDoc; - nsCOMPtr 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