diff options
author | Michael Stahl <mst@openoffice.org> | 2011-02-10 16:45:02 +0100 |
---|---|---|
committer | Michael Stahl <mst@openoffice.org> | 2011-02-10 16:45:02 +0100 |
commit | c5db3b93ee1058bd20ebcde2e757b52b9a67b74a (patch) | |
tree | d4c739c0e097f8bdd005e28dd1cecffaee593e33 /unoxml | |
parent | d76639d5d833a05a3181f7293e38a250dc6c1299 (diff) |
xmlfix3: unoxml: prevent invalid child-parent relationships:
new method CNode::IsChildTypeAllowed(NodeType).
use it in appendChild(), insertBefore(), replaceChild().
Diffstat (limited to 'unoxml')
-rw-r--r-- | unoxml/source/dom/attr.cxx | 11 | ||||
-rw-r--r-- | unoxml/source/dom/attr.hxx | 2 | ||||
-rw-r--r-- | unoxml/source/dom/document.cxx | 42 | ||||
-rw-r--r-- | unoxml/source/dom/document.hxx | 2 | ||||
-rw-r--r-- | unoxml/source/dom/documentfragment.cxx | 15 | ||||
-rw-r--r-- | unoxml/source/dom/documentfragment.hxx | 2 | ||||
-rw-r--r-- | unoxml/source/dom/element.cxx | 22 | ||||
-rw-r--r-- | unoxml/source/dom/element.hxx | 2 | ||||
-rw-r--r-- | unoxml/source/dom/entity.cxx | 15 | ||||
-rw-r--r-- | unoxml/source/dom/entity.hxx | 1 | ||||
-rw-r--r-- | unoxml/source/dom/entityreference.cxx | 15 | ||||
-rw-r--r-- | unoxml/source/dom/entityreference.hxx | 2 | ||||
-rw-r--r-- | unoxml/source/dom/node.cxx | 22 | ||||
-rw-r--r-- | unoxml/source/dom/node.hxx | 3 |
14 files changed, 147 insertions, 9 deletions
diff --git a/unoxml/source/dom/attr.cxx b/unoxml/source/dom/attr.cxx index bb73e20c7402..9790ecc3a140 100644 --- a/unoxml/source/dom/attr.cxx +++ b/unoxml/source/dom/attr.cxx @@ -70,6 +70,17 @@ namespace DOM return pNs; } + bool CAttr::IsChildTypeAllowed(NodeType const nodeType) + { + switch (nodeType) { + case NodeType_TEXT_NODE: + case NodeType_ENTITY_REFERENCE_NODE: + return true; + default: + return false; + } + } + OUString SAL_CALL CAttr::getNodeName() throw (RuntimeException) { diff --git a/unoxml/source/dom/attr.hxx b/unoxml/source/dom/attr.hxx index 6d9f6758c2c1..824f042a2b85 100644 --- a/unoxml/source/dom/attr.hxx +++ b/unoxml/source/dom/attr.hxx @@ -68,6 +68,8 @@ namespace DOM /// return the libxml namespace corresponding to m_pNamespace on pNode xmlNsPtr GetNamespace(xmlNodePtr const pNode); + virtual bool IsChildTypeAllowed(NodeType const nodeType); + /** Returns the name of this attribute. */ diff --git a/unoxml/source/dom/document.cxx b/unoxml/source/dom/document.cxx index 44f2c41309b2..1a7f47b9e621 100644 --- a/unoxml/source/dom/document.cxx +++ b/unoxml/source/dom/document.cxx @@ -56,6 +56,20 @@ namespace DOM { + static xmlNodePtr lcl_getDocumentType(xmlDocPtr const i_pDocument) + { + // find the doc type + xmlNodePtr cur = i_pDocument->children; + while (cur != NULL) + { + if ((cur->type == XML_DOCUMENT_TYPE_NODE) || + (cur->type == XML_DTD_NODE)) { + return cur; + } + } + return 0; + } + /// get the pointer to the root element node of the document static xmlNodePtr lcl_getDocumentRootPtr(xmlDocPtr const i_pDocument) { @@ -292,6 +306,24 @@ namespace DOM rContext.mxDocHandler->endDocument(); } + bool CDocument::IsChildTypeAllowed(NodeType const nodeType) + { + switch (nodeType) { + case NodeType_PROCESSING_INSTRUCTION_NODE: + case NodeType_COMMENT_NODE: + return true; + case NodeType_ELEMENT_NODE: + // there may be only one! + return 0 == lcl_getDocumentRootPtr(m_aDocPtr); + case NodeType_DOCUMENT_TYPE_NODE: + // there may be only one! + return 0 == lcl_getDocumentType(m_aDocPtr); + default: + return false; + } + } + + void SAL_CALL CDocument::addListener(const Reference< XStreamListener >& aListener ) throw (RuntimeException) { @@ -601,15 +633,9 @@ namespace DOM { ::osl::MutexGuard const g(m_Mutex); - // find the doc type - xmlNodePtr cur = m_aDocPtr->children; - while (cur != NULL) - { - if (cur->type == XML_DOCUMENT_TYPE_NODE || cur->type == XML_DTD_NODE) - break; - } + xmlNodePtr const pDocType(lcl_getDocumentType(m_aDocPtr)); Reference< XDocumentType > const xRet( - static_cast< XNode* >(GetCNode(cur).get()), + static_cast< XNode* >(GetCNode(pDocType).get()), UNO_QUERY); return xRet; } diff --git a/unoxml/source/dom/document.hxx b/unoxml/source/dom/document.hxx index 92235c08a720..6b4d5c6d619b 100644 --- a/unoxml/source/dom/document.hxx +++ b/unoxml/source/dom/document.hxx @@ -131,6 +131,8 @@ namespace DOM virtual void fastSaxify( Context& rContext ); + virtual bool IsChildTypeAllowed(NodeType const nodeType); + /** Creates an Attr of the given name. */ diff --git a/unoxml/source/dom/documentfragment.cxx b/unoxml/source/dom/documentfragment.cxx index ed94d639fab2..683938e7f1e4 100644 --- a/unoxml/source/dom/documentfragment.cxx +++ b/unoxml/source/dom/documentfragment.cxx @@ -37,6 +37,21 @@ namespace DOM { } + bool CDocumentFragment::IsChildTypeAllowed(NodeType const nodeType) + { + switch (nodeType) { + case NodeType_ELEMENT_NODE: + case NodeType_PROCESSING_INSTRUCTION_NODE: + case NodeType_COMMENT_NODE: + case NodeType_TEXT_NODE: + case NodeType_CDATA_SECTION_NODE: + case NodeType_ENTITY_REFERENCE_NODE: + return true; + default: + return false; + } + } + OUString SAL_CALL CDocumentFragment::getNodeName()throw (RuntimeException) { return OUString::createFromAscii("#document-fragment"); diff --git a/unoxml/source/dom/documentfragment.hxx b/unoxml/source/dom/documentfragment.hxx index afb3f04dc3bf..6236d5ca453a 100644 --- a/unoxml/source/dom/documentfragment.hxx +++ b/unoxml/source/dom/documentfragment.hxx @@ -55,6 +55,8 @@ namespace DOM xmlNodePtr const pNode); public: + virtual bool IsChildTypeAllowed(NodeType const nodeType); + // ---- resolve uno inheritance problems... // overrides for XNode base virtual OUString SAL_CALL getNodeName() diff --git a/unoxml/source/dom/element.cxx b/unoxml/source/dom/element.cxx index 1403fc4060a5..12ea9123294b 100644 --- a/unoxml/source/dom/element.cxx +++ b/unoxml/source/dom/element.cxx @@ -206,6 +206,28 @@ namespace DOM popContext(i_rContext); } + bool CElement::IsChildTypeAllowed(NodeType const nodeType) + { + switch (nodeType) { + case NodeType_ELEMENT_NODE: + case NodeType_TEXT_NODE: + case NodeType_COMMENT_NODE: + case NodeType_PROCESSING_INSTRUCTION_NODE: + case NodeType_CDATA_SECTION_NODE: + case NodeType_ENTITY_REFERENCE_NODE: + return true; + case NodeType_ATTRIBUTE_NODE: + /* this is not relly allowed by the DOM spec, but this + implementation has evidently supported it (by special case + handling, so the attribute does not actually become a child) + so allow it for backward compatiblity */ + return true; + default: + return false; + } + } + + /** Retrieves an attribute value by name. return empty string if attribute is not set diff --git a/unoxml/source/dom/element.hxx b/unoxml/source/dom/element.hxx index 119f30eca6ef..58891ed0d21c 100644 --- a/unoxml/source/dom/element.hxx +++ b/unoxml/source/dom/element.hxx @@ -66,6 +66,8 @@ namespace DOM virtual void fastSaxify( Context& i_rContext ); + virtual bool IsChildTypeAllowed(NodeType const nodeType); + /** Retrieves an attribute value by name. */ diff --git a/unoxml/source/dom/entity.cxx b/unoxml/source/dom/entity.cxx index dbf675f7765e..0e396d94eb00 100644 --- a/unoxml/source/dom/entity.cxx +++ b/unoxml/source/dom/entity.cxx @@ -41,6 +41,21 @@ namespace DOM { } + bool CEntity::IsChildTypeAllowed(NodeType const nodeType) + { + switch (nodeType) { + case NodeType_ELEMENT_NODE: + case NodeType_PROCESSING_INSTRUCTION_NODE: + case NodeType_COMMENT_NODE: + case NodeType_TEXT_NODE: + case NodeType_CDATA_SECTION_NODE: + case NodeType_ENTITY_REFERENCE_NODE: + return true; + default: + return false; + } + } + /** For unparsed entities, the name of the notation for the entity. */ diff --git a/unoxml/source/dom/entity.hxx b/unoxml/source/dom/entity.hxx index 5c88f6dfe8c8..671ad8af91cf 100644 --- a/unoxml/source/dom/entity.hxx +++ b/unoxml/source/dom/entity.hxx @@ -61,6 +61,7 @@ namespace DOM xmlEntityPtr const pEntity); public: + virtual bool IsChildTypeAllowed(NodeType const nodeType); /** For unparsed entities, the name of the notation for the entity. diff --git a/unoxml/source/dom/entityreference.cxx b/unoxml/source/dom/entityreference.cxx index 942156aedf76..0dda6bc3f495 100644 --- a/unoxml/source/dom/entityreference.cxx +++ b/unoxml/source/dom/entityreference.cxx @@ -39,6 +39,21 @@ namespace DOM { } + bool CEntityReference::IsChildTypeAllowed(NodeType const nodeType) + { + switch (nodeType) { + case NodeType_ELEMENT_NODE: + case NodeType_PROCESSING_INSTRUCTION_NODE: + case NodeType_COMMENT_NODE: + case NodeType_TEXT_NODE: + case NodeType_CDATA_SECTION_NODE: + case NodeType_ENTITY_REFERENCE_NODE: + return true; + default: + return false; + } + } + OUString SAL_CALL CEntityReference::getNodeName()throw (RuntimeException) { ::osl::MutexGuard const g(m_rMutex); diff --git a/unoxml/source/dom/entityreference.hxx b/unoxml/source/dom/entityreference.hxx index b4f20303b888..d4e349076453 100644 --- a/unoxml/source/dom/entityreference.hxx +++ b/unoxml/source/dom/entityreference.hxx @@ -57,6 +57,8 @@ namespace DOM xmlNodePtr const pNode); public: + virtual bool IsChildTypeAllowed(NodeType const nodeType); + // ---- resolve uno inheritance problems... // overrides for XNode base virtual OUString SAL_CALL getNodeName() diff --git a/unoxml/source/dom/node.cxx b/unoxml/source/dom/node.cxx index 68ceb9bfa3e4..4786606c16c0 100644 --- a/unoxml/source/dom/node.cxx +++ b/unoxml/source/dom/node.cxx @@ -289,6 +289,12 @@ namespace DOM // default: do nothing } + bool CNode::IsChildTypeAllowed(NodeType const /*nodeType*/) + { + // default: no children allowed + return false; + } + /** Adds the node newChild to the end of the list of children of this node. */ @@ -323,6 +329,11 @@ namespace DOM e.Code = DOMExceptionType_HIERARCHY_REQUEST_ERR; throw e; } + if (!IsChildTypeAllowed(pNewChild->m_aNodeType)) { + DOMException e; + e.Code = DOMExceptionType_HIERARCHY_REQUEST_ERR; + throw e; + } // check whether this is an attribute node; it needs special handling xmlNodePtr res = NULL; @@ -691,6 +702,11 @@ namespace DOM e.Code = DOMExceptionType_HIERARCHY_REQUEST_ERR; throw e; } + if (!IsChildTypeAllowed(pNewNode->m_aNodeType)) { + DOMException e; + e.Code = DOMExceptionType_HIERARCHY_REQUEST_ERR; + throw e; + } // attributes are unordered anyway, so just do appendChild if (XML_ATTRIBUTE_NODE == pNewChild->type) { @@ -828,7 +844,6 @@ namespace DOM if (!xOldChild.is() || !xNewChild.is()) { throw RuntimeException(); } - // XXX check node types if (xNewChild->getOwnerDocument() != getOwnerDocument()) { DOMException e; @@ -867,6 +882,11 @@ namespace DOM e.Code = DOMExceptionType_HIERARCHY_REQUEST_ERR; throw e; } + if (!IsChildTypeAllowed(pNewNode->m_aNodeType)) { + DOMException e; + e.Code = DOMExceptionType_HIERARCHY_REQUEST_ERR; + throw e; + } if( pOld->type == XML_ATTRIBUTE_NODE ) { diff --git a/unoxml/source/dom/node.hxx b/unoxml/source/dom/node.hxx index cf814b00f9f0..6d9c4afcfafb 100644 --- a/unoxml/source/dom/node.hxx +++ b/unoxml/source/dom/node.hxx @@ -154,6 +154,9 @@ namespace DOM // recursively create SAX events virtual void fastSaxify( Context& io_rContext ); + // constrains child relationship between nodes based on type + virtual bool IsChildTypeAllowed(NodeType const nodeType); + // ---- DOM interfaces /** |