GNOME Bugzilla – Bug 682072
xmlDOMWrapCloneNode leaves reference in the destNode to a namespace from the sourceDoc
Last modified: 2021-07-05 13:25:20 UTC
The following is code that exposes the problem: The symptom is that when the document with the new node is dumped a namespace object that is already freed is accessed. #include "libxml/parser.h" #include "libxml/tree.h" #include <string> static void dump(const xmlDocPtr pDoc, std::string& xmlContent) { xmlChar* outBuf; int outSize; xmlDocDumpFormatMemory(pDoc, &outBuf, &outSize, TRUE); xmlContent = std::string((const char *) outBuf); xmlFree(outBuf); } int main(int argc, char **argv) { std::string str = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>" "<w:settings xmlns:m=\"http://schemas.openxmlformats.org/officeDocument/2006/math\"" " xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\">" "<m:mathPr>" "<m:mathFont m:val=\"Cambria Math\"/>" "</m:mathPr>" "</w:settings>"; xmlParserCtxtPtr context = xmlNewParserCtxt(); if (context == NULL) return 1; xmlDocPtr pDoc = xmlCtxtReadMemory(context, str.c_str(), (int)str.size(), "dummy1.xml", NULL, 0); xmlFreeParserCtxt(context); xmlNodePtr root1 = xmlDocGetRootElement(pDoc); { xmlDocPtr doc2 = xmlNewDoc(BAD_CAST "1.0"); doc2->standalone = TRUE; xmlNodePtr root = xmlNewDocNode(doc2, NULL, BAD_CAST "settings", NULL); if (root == NULL) return 1; xmlDocSetRootElement(doc2, root); xmlNsPtr ns = xmlNewNs(root, BAD_CAST "http://schemas.openxmlformats.org/wordprocessingml/2006/main", BAD_CAST "w"); if (ns == NULL) return 1; xmlSetNs(root, ns); xmlNsPtr mns = xmlNewNs(root, BAD_CAST "http://schemas.openxmlformats.org/officeDocument/2006/math", BAD_CAST "m"); if (mns == NULL) return 1; xmlNodePtr mathPr = xmlNewDocNode(doc2, mns, BAD_CAST"mathPr", NULL); xmlNodePtr mathFont = root1->children->children; xmlNodePtr newChildNode; xmlDOMWrapCloneNode(NULL, // xmlDOMWrapCtxtPtr - optional mathFont->doc, // sourceDoc (must not be NULL) mathFont, // node to clone &newChildNode, // destNode mathPr->doc, // destDoc mathPr, // destParent TRUE, // deep = clone children 0 // options (ATTRIBUTE_UNUSED) ); xmlAddChild(mathPr, newChildNode); xmlAddChild(root, mathPr); xmlFreeDoc(pDoc); std::string outStr; dump(doc2, outStr); xmlFreeDoc(doc2); } return 0; }
Note that destParent mathPr is unlinked at the time xmlDOMWrapCloneNode is called. It seems like the method works fine if it is.
GNOME is going to shut down bugzilla.gnome.org in favor of gitlab.gnome.org. As part of that, we are mass-closing older open tickets in bugzilla.gnome.org which have not seen updates for a longer time (resources are unfortunately quite limited so not every ticket can get handled). If you can still reproduce the situation described in this ticket in a recent and supported software version, then please follow https://wiki.gnome.org/GettingInTouch/BugReportingGuidelines and create a new ticket at https://gitlab.gnome.org/GNOME/libxml2/-/issues/ Thank you for your understanding and your help.