Skip to content

Instantly share code, notes, and snippets.

@flavorjones
Created November 4, 2010 16:42
Show Gist options
  • Save flavorjones/662758 to your computer and use it in GitHub Desktop.
Save flavorjones/662758 to your computer and use it in GitHub Desktop.
demonstrates libxml2 bug in xmlSAX2StartElementNs
#include <stdio.h>
#include <libxml/tree.h>
int main(int argc, char** argv)
{
xmlDocPtr doc1, doc2 ;
xmlNodePtr fragment ;
xmlNodePtr parent ;
xmlNodePtr child ;
/* nokogiri: fragment = Nokogiri::XML.fragment("<div></div>") */
doc1 = xmlReadMemory("<root><div></div></root>", 25, NULL, NULL, 0);
parent = xmlDocGetRootElement(doc1)->children ;
doc2 = xmlNewDoc((const xmlChar*)"1.0");
fragment = xmlNewDocFragment(doc2);
xmlUnlinkNode(parent);
parent = xmlAddChild(fragment, xmlDocCopyNode(parent, fragment->doc, 1));
/* nokogiri: child = parent.send(:in_context, "<h1></h1>", 0).first */
xmlParseInNodeContext(parent, "<h1></h1>", 10, 0, &child);
printf("the parent of my child should be me:");
printf("doc2 %p, doc2->children %p, doc2->children->parent %p\n",
doc2, doc2->children, doc2->children ? doc2->children->parent : NULL);
xmlUnlinkNode(child);
xmlAddChild(parent, child);
/*
* and the grand finale ... a resulting crash
*/
/* nokogiri: (document dealloc) */
xmlAddChild((xmlNodePtr)doc2, fragment);
xmlFreeDoc(doc2);
xmlFreeDoc(doc1);
exit(0);
}
diff --git a/SAX2.c b/SAX2.c
index 84c1f00..fac870d 100644
--- a/SAX2.c
+++ b/SAX2.c
@@ -2264,6 +2264,7 @@ xmlSAX2StartElementNs(void *ctx,
* Link the child element
*/
if (parent != NULL) {
+ xmlUnlinkNode(ret);
if (parent->type == XML_ELEMENT_NODE) {
xmlAddChild(parent, ret);
} else {
foo: foo.o
$(CC) foo.o -g -o foo -lxml2
foo.o: foo.c
$(CC) foo.c -g -Wall -c -o foo.o -I/usr/include/libxml2
clean:
rm -f foo foo.o
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment