summaryrefslogtreecommitdiff
path: root/unoxml
diff options
context:
space:
mode:
authorMichael Stahl <mst@openoffice.org>2011-02-10 16:45:02 +0100
committerMichael Stahl <mst@openoffice.org>2011-02-10 16:45:02 +0100
commitc5db3b93ee1058bd20ebcde2e757b52b9a67b74a (patch)
treed4c739c0e097f8bdd005e28dd1cecffaee593e33 /unoxml
parentd76639d5d833a05a3181f7293e38a250dc6c1299 (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.cxx11
-rw-r--r--unoxml/source/dom/attr.hxx2
-rw-r--r--unoxml/source/dom/document.cxx42
-rw-r--r--unoxml/source/dom/document.hxx2
-rw-r--r--unoxml/source/dom/documentfragment.cxx15
-rw-r--r--unoxml/source/dom/documentfragment.hxx2
-rw-r--r--unoxml/source/dom/element.cxx22
-rw-r--r--unoxml/source/dom/element.hxx2
-rw-r--r--unoxml/source/dom/entity.cxx15
-rw-r--r--unoxml/source/dom/entity.hxx1
-rw-r--r--unoxml/source/dom/entityreference.cxx15
-rw-r--r--unoxml/source/dom/entityreference.hxx2
-rw-r--r--unoxml/source/dom/node.cxx22
-rw-r--r--unoxml/source/dom/node.hxx3
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
/**