Kaydet (Commit) c5db3b93 authored tarafından Michael Stahl's avatar Michael Stahl

xmlfix3: unoxml: prevent invalid child-parent relationships:

 new method CNode::IsChildTypeAllowed(NodeType).
 use it in appendChild(), insertBefore(), replaceChild().
üst d76639d5
......@@ -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)
{
......
......@@ -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.
*/
......
......@@ -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;
}
......
......@@ -131,6 +131,8 @@ namespace DOM
virtual void fastSaxify( Context& rContext );
virtual bool IsChildTypeAllowed(NodeType const nodeType);
/**
Creates an Attr of the given name.
*/
......
......@@ -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");
......
......@@ -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()
......
......@@ -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
......
......@@ -66,6 +66,8 @@ namespace DOM
virtual void fastSaxify( Context& i_rContext );
virtual bool IsChildTypeAllowed(NodeType const nodeType);
/**
Retrieves an attribute value by name.
*/
......
......@@ -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.
*/
......
......@@ -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.
......
......@@ -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);
......
......@@ -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()
......
......@@ -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 )
{
......
......@@ -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
/**
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment