Reputation: 115
We're using libxml2 to resolve xpaths against an xmlcontext which contains "registered" vars. Our destructor attempts to clean up an xmlXPathContextPtr and a xmlDocPtr:
~CLibXpathContext()
{
xmlXPathFreeContext(m_xpathContext); //causes crash if any vars registered
xmlFreeDoc(m_xmlDoc);
}
We're registering vars as follows:
virtual bool addVariable(const char * name, const char * val) override
{
if (m_xpathContext )
{
xmlXPathObjectPtr valx = xmlXPathWrapCString((char*)val);
return xmlXPathRegisterVariable(m_xpathContext, (xmlChar *)name, valx) == 0;
}
return false;
}
The libxml2 cleanup code is as follows:
void xmlXPathFreeContext(xmlXPathContextPtr ctxt) {
if (ctxt == NULL) return;
if (ctxt->cache != NULL)
xmlXPathFreeCache((xmlXPathContextCachePtr) ctxt->cache);
xmlXPathRegisteredNsCleanup(ctxt);
xmlXPathRegisteredFuncsCleanup(ctxt);
xmlXPathRegisteredVariablesCleanup(ctxt); // this is causing the issue
xmlResetError(&ctxt->lastError);
xmlFree(ctxt);
}
Any ideas what I might be doing wrong, or if the libxml2 code has an issue?
We also attempted to unregister all registered vars before calling the xmlXPathFreeContext method...
Upvotes: 0
Views: 335
Reputation: 33658
You have to use xmlXPathNewCString(const char *)
instead of xmlXPathWrapCString(char *)
. The former creates a copy of the string while the latter transfers ownership of the string to the XPath object, freeing the original string when the XPath object is destroyed.
Upvotes: 1