GNOME Bugzilla – Bug 338306
RelaxNG: freeing the parser context after parsing a non-RNG document crashes
Last modified: 2017-06-12 19:05:59 UTC
Steps to reproduce: 1. create an RNG parser context (xmlRelaxNGNewDocParserCtxt) for a non-RNG document (like "<test/>") 2. call xmlRelaxNGParse 3. free the context Step 3 will call xmlFreeDoc and crash. Stack trace: From Valgrind (test with lxml): ==23438== Invalid read of size 8 ==23438== at 0x63456EB: xmlFreeDoc (in /usr/lib64/libxml2.so.2.6.23) ==23438== by 0x63C1AAB: xmlRelaxNGFreeParserCtxt (in /usr/lib64/libxml2.so.2.6.23) ==23438== by 0x60A2E37: __pyx_f_5etree_7RelaxNG___init__ (in /home/me/source/Python/lxml/lxml-HEAD/src/lxml/etree.so) ==23438== by 0x4B7C67C: (within /usr/lib64/libpython2.4.so.1.0) ==23438== by 0x0: ??? ==23438== Address 0x6C080B8 is 152 bytes inside a block of size 168 free'd ==23438== at 0x4A1A5E3: free (in /usr/lib64/valgrind/amd64-linux/vgpreload_memcheck.so) ==23438== by 0x634584F: xmlFreeDoc (in /usr/lib64/libxml2.so.2.6.23) ==23438== by 0x63C223F: xmlRelaxNGParse (in /usr/lib64/libxml2.so.2.6.23) ==23438== by 0x60A2E26: __pyx_f_5etree_7RelaxNG___init__ (in /home/me/source/Python/lxml/lxml-HEAD/src/lxml/etree.so) ==23438== by 0x4B7C67C: (within /usr/lib64/libpython2.4.so.1.0) ==23438== by 0x0: ??? [...] ==23438== Invalid free() / delete / delete[] ==23438== at 0x4A1A5E3: free (in /usr/lib64/valgrind/amd64-linux/vgpreload_memcheck.so) ==23438== by 0x634584F: xmlFreeDoc (in /usr/lib64/libxml2.so.2.6.23) ==23438== by 0x63C1AAB: xmlRelaxNGFreeParserCtxt (in /usr/lib64/libxml2.so.2.6.23) ==23438== by 0x60A2E37: __pyx_f_5etree_7RelaxNG___init__ (in /home/me/source/Python/lxml/lxml-HEAD/src/lxml/etree.so) ==23438== by 0x4B7C67C: (within /usr/lib64/libpython2.4.so.1.0) ==23438== by 0x0: ??? ==23438== Address 0x6C08020 is 0 bytes inside a block of size 168 free'd ==23438== at 0x4A1A5E3: free (in /usr/lib64/valgrind/amd64-linux/vgpreload_memcheck.so) ==23438== by 0x634584F: xmlFreeDoc (in /usr/lib64/libxml2.so.2.6.23) ==23438== by 0x63C223F: xmlRelaxNGParse (in /usr/lib64/libxml2.so.2.6.23) ==23438== by 0x60A2E26: __pyx_f_5etree_7RelaxNG___init__ (in /home/me/source/Python/lxml/lxml-HEAD/src/lxml/etree.so) ==23438== by 0x4B7C67C: (within /usr/lib64/libpython2.4.so.1.0) ==23438== by 0x0: ??? Other information:
Annoying, xmlRelaxNGNewDocParserCtxt is not the most commonly used API, the tree need to be copied anyway, which is slower than reparsing from scratch (surprizing but true). Anyway the bug is fixed in CVS, thanks for the report ! paphio:~/XML -> cat tst.c #include <stdio.h> #include <libxml/parser.h> #include <libxml/tree.h> #include <libxml/relaxng.h> int main(int argc, char **argv) { xmlDocPtr schemas; xmlRelaxNGParserCtxtPtr ctxt; xmlRelaxNGPtr res; if (argc != 2) return(1); LIBXML_TEST_VERSION schemas = xmlReadFile(argv[1], NULL, 0); if (schemas == NULL) { fprintf(stderr, "Failed to parse %s\n", argv[1]); exit(0); } ctxt = xmlRelaxNGNewDocParserCtxt(schemas); if (ctxt == NULL) { fprintf(stderr, "Failed to build RNG parser from %s\n", argv[1]); exit(0); } res = xmlRelaxNGParse(ctxt); if (res != NULL) { fprintf(stderr, "%s is actually an RNG schemas\n", argv[1]); exit(0); } else { fprintf(stderr, "%s is not an RNG schemas, freeing\n", argv[1]); } xmlRelaxNGFreeParserCtxt(ctxt); xmlFreeDoc(schemas); xmlCleanupParser(); xmlMemoryDump(); return(0); } paphio:~/XML -> valgrind --leak-check=full --leak-resolution=high ./tst test.xml test.xml:0: Relax-NG parser error : xmlRelaxNGParse: schemas is empty test.xml is not an RNG schemas, freeing paphio:~/XML -> Daniel
Created attachment 87501 [details] 338306