Hi,

        I'm using xmlParseBalancedChunkMemory to parse a XML fragment that 
I want to attach to a document. If the fragment contains an 
external entity reference &ext; for an entity that has been 
declared in the document's DTD but not yet parsed (i.e. the main 
document does not contain &ext;), I get a segmentation fault when I 
attempt to free the parsed nodes. If on the other hand the main 
document contains &ext; everything just works. 

I'm attaching a full example (foo.c - modified parse1.c example) and 
sample XML files I use (foo1.xml passed as ARG to ./foo, e2.xml is 
the external entity), but in brief, the code looks like this:

 xmlNodePtr nodes = NULL;
 doc = xmlReadFile("foo1.xml", NULL, 0);
 if (doc == NULL) return;
 xmlParseBalancedChunkMemory( doc, NULL, NULL, 0, "&ext;", &nodes );
 if (nodes)
    xmlFreeNodeList(nodes); /* this causes a SIGSEGV */
 xmlFreeDoc(doc);

If the file "foo1.xml" contains 

<!DOCTYPE doc [
<!ENTITY ext SYSTEM "e2.xml">
]
<doc>&ext;</doc>

it works, if the last line is just "<doc/>", it fails.

The output from valgrind indicates a double free (see below).

Any hints?

==22130== Invalid read of size 4
==22130==    at 0x4042D35: xmlFreeNodeList (tree.c:3376)
==22130==    by 0x4023CE5: xmlFreeEntity (entities.c:107)
==22130==    by 0x404BA03: xmlHashFree (hash.c:307)
==22130==    by 0x40247DD: xmlFreeEntitiesTable (entities.c:758)
==22130==    by 0x404314D: xmlFreeDtd (tree.c:1111)
==22130==    by 0x4043285: xmlFreeDoc (tree.c:1213)
==22130==    by 0x804869C: example1Func 
(in /export/home/pajas/projects/XML-LibXML-devel/XML-LibXML/foo)
==22130==    by 0x80486E2: main 
(in /export/home/pajas/projects/XML-LibXML-devel/XML-LibXML/foo)
==22130==  Address 0x41202D8 is 80 bytes inside a block of size 88 
free'd
==22130==    at 0x40050FF: free (vg_replace_malloc.c:233)
==22130==    by 0x4043365: xmlFreeDoc (tree.c:1223)
==22130==    by 0x403E068: xmlParseBalancedChunkMemoryRecover 
(parser.c:12098)
==22130==    by 0x403E1F6: xmlParseBalancedChunkMemory 
(parser.c:11562)
==22130==    by 0x8048686: example1Func 
(in /export/home/pajas/projects/XML-LibXML-devel/XML-LibXML/foo)
==22130==    by 0x80486E2: main 
(in /export/home/pajas/projects/XML-LibXML-devel/XML-LibXML/foo)

This is on a 32bit FC7, with libxml2 2.7.2.

Thanks,

-- Petr
/* @(#)foo.c
 */

#include <unistd.h>
#include <libxml/parser.h>
#include <libxml/tree.h>

static void
example1Func(const char *filename) {
    xmlDocPtr doc; /* the resulting document tree */
    xmlNodePtr nodes  = NULL;

    doc = xmlReadFile(filename, NULL, 0);
    if (doc == NULL) {
        fprintf(stderr, "Failed to parse %s\n", filename);
	return;
    }
    
    xmlParseBalancedChunkMemory( doc, NULL, NULL, 0, "&ext;", &nodes );
    if (nodes) xmlFreeNodeList(nodes);
    xmlFreeDoc(doc);
}
int main(int argc, char **argv) {
    if (argc != 2)
        return(1);
    LIBXML_TEST_VERSION
    example1Func(argv[1]);
    xmlCleanupParser();
    return(0);
}
<foo>test</foo>
<?xml version='1.0'?>
<!DOCTYPE doc [
<!ENTITY ext SYSTEM "e2.xml">
]>
<doc/>
_______________________________________________
xml mailing list, project page  http://xmlsoft.org/
[email protected]
http://mail.gnome.org/mailman/listinfo/xml

Reply via email to