[xml] Freeing Input buffer after DTD parse



libxml2: 2.3.13

If I free the input buffer after I've parsed a DTD from a string, I get a
segfault from libc somewhere. I have had a great deal of difficulty
tracking this down, so I'm posting here in case someone else has seen
this. This is perl XS code, but it's basically plain C.

The line below where I free the InputBuffer causes the segfault. As long
as that is commented out the code runs fine, though it leaks memory, of
course. Note that I have tried creating a new string copy of str using
xmlStrdup, so that freeing the InputBuffer will de-allocate the new
string, but that doesn't help. Backtraces don't help either, as the
segfault appears to come from a later malloc coming from nowhere.

The backtrace:

(gdb) run -Iblib/arch -Iblib/lib t/13dtd.t
Starting program: /usr/bin/perl -Iblib/arch -Iblib/lib t/13dtd.t
1..9
ok 1
ok 2
ok 3

Program received signal SIGSEGV, Segmentation fault.
chunk_alloc (ar_ptr=0x244860, nb=56) at malloc.c:2830
2830    malloc.c: No such file or directory.
(gdb) bt
#0  chunk_alloc (ar_ptr=0x244860, nb=56) at malloc.c:2830
#1  0x1b61ca in __libc_malloc (bytes=48) at malloc.c:2651
(gdb)

Here's the code (this version works - uncomment the
xmlFreeParserInputBuffer and it segfaults without fail).

ProxyObject *
parse_string(CLASS, str, ...)
        char * CLASS
        char * str
    PREINIT:
        STRLEN n_a;
        xmlDtdPtr res;
        SV * encoding_sv;
        xmlParserInputBufferPtr buffer;
        xmlCharEncoding enc = XML_CHAR_ENCODING_NONE;
    CODE:
        LibXML_error = sv_2mortal(newSVpv("", 0));
        if (items > 2) {
            encoding_sv = ST(2);
            if (items > 3) {
                croak("parse_string: too many parameters");
            }
            /* warn("getting encoding...\n"); */
            enc = xmlParseCharEncoding(SvPV(encoding_sv, n_a));
            if (enc == XML_CHAR_ENCODING_ERROR) {
                croak("Parse of encoding %s failed: %s", SvPV(encoding_sv, n_a), SvPV(LibXML_error, n_a));
            }
        }
        /* warn("make buffer\n"); */
        buffer = xmlAllocParserInputBuffer(enc);
        /* xmlParserInputBufferCreateMem(str, strlen(str), enc); */
        xmlParserInputBufferPush(buffer, strlen(str), str);
        /* warn("parse\n"); */
        res = xmlIOParseDTD(NULL, buffer, enc);
        /* warn("free : 0x%x\n", buffer); */
        /* NOTE: For some reason freeing this InputBuffer causes a segfault! */
        /* xmlFreeParserInputBuffer(buffer); */
        /* warn("make proxy\n"); */
        if (res != NULL) {
            RETVAL = make_proxy_node((xmlNodePtr)res);
        }
        else {
            croak("couldn't parse DTD: %s", SvPV(LibXML_error, n_a));
        }
        /* warn("return\n"); */
    OUTPUT:
        RETVAL

-- 
<Matt/>

    /||    ** Founder and CTO  **  **   http://axkit.com/     **
   //||    **  AxKit.com Ltd   **  ** XML Application Serving **
  // ||    ** http://axkit.org **  ** XSLT, XPathScript, XSP  **
 // \\| // ** mod_perl news and resources: http://take23.org  **
     \\//
     //\\
    //  \\






[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]