From: Anders Karlsson (pugo@cendio.se)
Date: Wed Jan 31 2001 - 10:23:04 EST
I have now digged deeper into the libxml code and found two bugs in the
implementation om xmlCopyDoc.
There is a patch attatched to this document.
Bug 1: Missing 'charset' copy in xmlCopyDoc
-------------------------------------------
In 'xmlCopyDoc' in tree.c the variable 'charset' should be copied, but
this is missing. This causes problems when using 'xmlDocDump' since it
tries to read the charset variable.
This should be fixed by adding the following line:
ret->charset = doc->charset;
Bug 2: Casting problems in xmlCopyDoc
-------------------------------------
When calling xmlCopyDoc with recursive=1 it uses xmlStaticCopyNodeList
to copy the node tree, which in turn uses xmlStaticCopyNode.
xmlStaticCopyNode returns a 'static xmlNodePtr' containing the new
node. It does not look at the type variable whether it is a
xmlNodePtr or not.
The problem comes when using xmlDocDump, which uses
xmlDocContentDumpOutput to dump the contents. This function calls
xmlNodeDumpOutput to dump the nodes.
xmlNodeDumpOutput looks at the type variable and if it is a XML_DTD_NODE
it runs:
xmlDtdDumpOutput(buf, (xmlDtdPtr) cur, encoding);
Here it casts "cur" (which is the xmlNodePtr pointing to the xmlNode
created by the copy described above) to a xmlDtdPtr.
The function "xmlDtdDumpOutput" then tries the following:
xmlDtdDumpOutput(xmlOutputBufferPtr buf, xmlDtdPtr dtd, const char
*encoding)
{
.
. (cut)
.
if (dtd->ExternalID != NULL) {
xmlOutputBufferWriteString(buf, " PUBLIC ");
xmlBufferWriteQuotedString(buf->buffer, dtd->ExternalID);
xmlOutputBufferWriteString(buf, " ");
xmlBufferWriteQuotedString(buf->buffer, dtd->SystemID);
} else if (dtd->SystemID != NULL) {
.
.
I.e. it tries to read the "ExternalID" from the "xmlDtdPtr", but since
this is a "xmlNodePtr" casted to a "xmlDtdPtr" it doesn't contain the
ExternalID. When "xmlBufferWriteQuotedString" tries to dump the
information is segfaults.
This can be solved by checking the type when copying the nodes in
xmlStaticCopyNodeList and if it is a DTD node it should be copied with
xmlCopyDtd instead:
static xmlNodePtr
xmlStaticCopyNodeList(xmlNodePtr node, xmlDocPtr doc, xmlNodePtr parent) {
xmlNodePtr ret = NULL;
xmlNodePtr p = NULL,q;
while (node != NULL) {
if( node->type == XML_DTD_NODE )
q = (xmlNodePtr) xmlCopyDtd( (xmlDtdPtr) node );
else
q = xmlStaticCopyNode(node, doc, parent, 1);
if (ret == NULL) {
q->prev = NULL;
ret = p = q;
} else {
p->next = q;
q->prev = p;
p = q;
}
node = node->next;
}
return(ret);
}
Regards,
--------------------------------------------------------------------------
Anders Karlsson Email: anders.karlsson@cendio.se
Cendio Systems AB WWW: www.cendio.se
Teknikringen 3, Voice: +46 - (0)13 - 21 46 00
SE-583 30 LINKÖPING, SWEDEN Fax: +46 - (0)13 - 21 47 00
---- Message from the list xml@rpmfind.net Archived at : http://xmlsoft.org/messages/ to unsubscribe: echo "unsubscribe xml" | mail majordomo@rpmfind.net
This archive was generated by hypermail 2b29 : Wed Jan 31 2001 - 10:46:24 EST