Enabled 1 Enabled 1 Enabled 1

Setting root element from the same XML doc results in memory leak

202 views Asked by At

I have an XML as follows:

xmlChar *xml_in:

<rpc-reply xmlns:abc="http://xml.myorg.net/">
<a myorg:style="abc-myorg">
<b>Enabled</b>
<c>1</c>
</a>
<cli>
<banner></banner>
</cli>
</rpc-reply>

I want to covert the above to following:

<a myorg:style="abc-myorg">
<b>Enabled</b>
<c>1</c>
</a>

Here is what I'm doing:

void
strip_namespace (xmlNodePtr node)
{
    if (node == NULL) {
        return;
    }

    xmlSetNs(node, NULL);

    for (node = node->children; node; node = node->next) {
        strip_namespace(node);
    }
}

xmlNodePtr
get_first_element (xmlNodePtr node)
{
    for (; node; node = node->next) {
        if (node->type == XML_ELEMENT_NODE) {
            return node;
        }
    }

    return NULL;
}


xmlDocPtr doc;
xmlNodePtr root, tmp_node;

doc = xmlReadDoc((const xmlChar *) xml_in, NULL, NULL, XML_PARSE_NODICT);
root = xmlDocGetRootElement(doc);

if (0 == strcmp((const char *) root->name, "rpc-reply")) {
    root = get_first_element(root->children);
    tmp_node = xmlDocSetRootElement(doc, root);

    strip_namespace(root);
    return doc;
}

The xmlDocPtr is used to walk the tree and then later freed using xmlFreeDoc.

However the above results in memory leak in valgrind report, even though xml_in and doc are later freed using libxml2's appropriate free functions.

I understand I'm probably doing it in the wrong way, but I would appreciate if you could share the correct code snippet to illustrate how this should be done.

Please also suggest if you observe any other potential issues in the above code.

What I tried: 1)

tmp_node = xmlDocSetRootElement(doc, root);
xmlUnlinkNode(tmp_node); // Tried to unlink the node, but leaks remains the same.
tmp_node = xmlDocSetRootElement(doc, root);
xmlFreeNode(tmp_node); // Tried to free the node, but application crashes.
tmp_node = xmlDocSetRootElement(doc, root);
xmlUnlinkNode(tmp_node); // Tried to unlink the node first.
xmlFreeNode(tmp_node); // Tried to free the node, but application crashes.
  1. Instead of xmlDocSetRootElement tried to use xmlReplaceNode:

new_root = get_first_element(root->children);

root = xmlReplaceNode(root, new_root);

Leaks still remain the same. Then I tried adding xmlUnlinkNode(root) and xmlFreeNode(root) after xmlReplaceNode similar to above 3 combination i.e. 1), 2), 3) but the behavior is same.

0

There are 0 answers