[xml] suggestions to workaround a segmentation fault



Hallo Daniel, All,

First of all, I'd like to thank you for all the new stuff in 2.6.  For
example, the new xmlReadXY parser API functions and the new syntax for
parsing options. It simplifies and shortens the code and makes it much
more readable and more joy to write. Also, I found the new dictionary
code saves me over 20% of memory for my complex >20Mb XML files and
the parser seems even faster then before.

Now, I'm still stuck with a problem related to xmlRemoveID. I really
need to find a workaround for this to continue my work (there is still
a lot to do on libxml2 Perl binding:-)). I tried to fix it with a
patch to libxml2, but the patch was rejected. Ok then, can somebody at
least give me a clue on how to workaround the segmentation faults
demonstrated in the test-case below.

In my application, I don't have a control over what nodes are queried
and what nodes are removed. This is up to the user. The problem is,
that once a validating parser hashed an ID, xmlGetID returns the
pointer to the node even if the node was already unlinked from the
document and freed, and I can't failed to find a way to check that the
pointer is still valid.

IMO, the problem is, that current xmlRemoveID is semantically
equivallent to

int
xmlRemoveID(xmlDocPtr* doc, xmlDocPtr attr) {
  return(-1);
}

Here is a simple test case. I compile it with
gcc `xml2-config --libs --cflags` -o test test.c
on RedHat 9 and RedHat Enterprise Server.

Any advice appreciated.

Thank you,
_____
#include <unistd.h>
#include <libxml/parser.h>
#include <libxml/valid.h>
#include <libxml/tree.h>

char* xmldoc = 
"<?xml version='1.0'?>"
"<!DOCTYPE foo ["
"<!ELEMENT foo (foo*)>"
"<!ATTLIST foo id ID #IMPLIED>]>"
"<foo>"
"  <foo id='F'/>"
"</foo>";


int
main (void) {
    xmlDocPtr doc;
    xmlAttrPtr attr;
    xmlNodePtr node;
    char * foo;
    doc = xmlReadMemory(xmldoc, strlen(xmldoc), NULL, NULL, XML_PARSE_DTDVALID);

    attr = xmlGetID(doc,"F");
    if (attr == NULL || attr->parent == NULL) {
        printf("error: node with id F not found\n");
        return(1);
    }
    printf("Unlinking node with id F\n");
    node=attr->parent;
    xmlUnlinkNode(node);
    xmlFree(node); /* this calls xmlRemoveID */

    attr = xmlGetID(doc,"F");
    if (attr == NULL || attr->parent == NULL) {
        printf("good, id F not found\n");
        return(0);
    }
    printf("ID still there? ok, let's fix it\n");
    xmlRemoveID(doc,attr);

    attr = xmlGetID(doc,"F");
    if (attr == NULL || attr->parent == NULL) {
        printf("ok, id F not found\n");
        return(0);
    }
    node=attr->parent;

    printf("Hm, still there. What else can I do?\n");
    printf("Let's trust the node exists then!\n");

    xmlNodeSetName(node, "FOO"); /* segmentation fault */

    printf("Still alive? that's surprising!\n");
}

_______

-- Petr



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