DTD parser changed in 2.14, now throws error

First of all, thank you for the clue stick re -1 for the size, I totally misinterpreted the description of the change…

As for providing a test for the free() issue, of course I can’t… The oldest version I could find atm was 2.12.10 and naturally xmlFreeParserInputBuffer() segfaulted there too with an invalid pointer / double free after using xmlIOParseDTD().

It was this silly snippet, btw:

#define KC_DTD  "\
<!ELEMENT kc (keychain)*> \
\
<!ELEMENT keychain (key)*> \
<!ATTLIST keychain \
        nme CDATA #REQUIRED \
        dscription CDATA #REQUIRED \
        ceated CDATA #REQUIRED \
        mdified CDATA #REQUIRED> \
\
<!ELEMENT key EMPTY> \
<!ATTLIST key \
        name CDATA #REQUIRED \
        value CDATA #REQUIRED \
        created CDATA #REQUIRED \
        modified CDATA #REQUIRED> \
"

#include <stdio.h>
#include <stdlib.h>

#include <libxml/parser.h>
#include <libxml/xmlversion.h>


int main(int argc, char *argv[]) {
        xmlParserInputBufferPtr buf = NULL;
        xmlDtdPtr               dtd = NULL;


        buf = xmlParserInputBufferCreateMem(KC_DTD,
                sizeof(KC_DTD) - (LIBXML_VERSION < 21401 ? 0 : 1),
                XML_CHAR_ENCODING_NONE);
        if (!buf) {
                xmlGenericError(xmlGenericErrorContext, "ERROR: Could not allocate buffer for DTD.\n");
                exit(1);
        }

        dtd = xmlIOParseDTD(NULL, buf, XML_CHAR_ENCODING_NONE);
        if (!dtd) {
                xmlGenericError(xmlGenericErrorContext, "ERROR: Could not parse DTD.\n");
                exit(1);
        }

        xmlFreeParserInputBuffer(buf);
        /*
        xmlFreeParserInputBuffer(buf);
        */
}

So either I tested this veery long ago (the commit for the comment in my code dates back to 2013, I’m not even sure which version I was using back then), or it was never actually an issue; it might’ve been that it was on a code path that was already exiting (thus the cleaning up) because of the validation issue, and I actually missed the memory corruption late in the game.

I wouldn’t be surprised if the code for xmlIOParseDTD() in libxml or at least the part that does its clean-up would not have been touched for at least as long a time, too, and it was simply PEBKAC on my end.

Anyway, thanks again for the quick pointer!

Daniel