Commit 37fce46f authored by Olivier Bertrand's avatar Olivier Bertrand

- Fix memory leak in libdoc.cpp in LIBXMLDOC::GetNodeList replacing

  xmlXPathFreeNodeSetList(Xop);         // Caused memory leak, by
  xmlXPathFreeObject(Xop);

modified:
  storage/connect/libdoc.cpp
parent 29f10f0f
......@@ -30,6 +30,53 @@ extern char version[];
extern int trace;
} // "C"
#if defined(_DEBUG)
static xmlFreeFunc Free;
static xmlMallocFunc Malloc;
static xmlMallocFunc MallocA;
static xmlReallocFunc Realloc;
static xmlStrdupFunc Strdup;
void xmlMyFree(void *mem)
{
if (trace)
htrc("Freeing at %p\n", mem);
Free(mem);
} // end of xmlMyFree
void *xmlMyMalloc(size_t size)
{
void *p = Malloc(size);
if (trace)
htrc("Allocating %.5d at %p\n", size, p);
return p;
} // end of xmlMyMalloc
void *xmlMyMallocAtomic(size_t size)
{
void *p = MallocA(size);
if (trace)
htrc("Atom alloc %.5d at %p\n", size, p);
return p;
} // end of xmlMyMallocAtomic
void *xmlMyRealloc(void *mem, size_t size)
{
void *p = Realloc(mem, size);
if (trace)
htrc("ReAlloc %.5d to %p from %p\n", size, p, mem);
return p;
} // end of xmlMyRealloc
char *xmlMyStrdup(const char *str)
{
char *p = Strdup(str);
if (trace)
htrc("Duplicating to %p from %p %s\n", p, str, str);
return p;
} // end of xmlMyStrdup
#endif // _DEBUG
/******************************************************************/
/* Return a LIBXMLDOC as a XMLDOC. */
/******************************************************************/
......@@ -44,6 +91,17 @@ PXDOC GetLibxmlDoc(PGLOBAL g, char *nsl, char *nsdf,
/******************************************************************/
void XmlInitParserLib(void)
{
#if defined(_DEBUG)
int rc = xmlGcMemGet(&Free, &Malloc, &MallocA, &Realloc, &Strdup);
if (!rc)
rc = xmlGcMemSetup(xmlMyFree,
xmlMyMalloc,
xmlMyMallocAtomic,
xmlMyRealloc,
xmlMyStrdup);
#endif // _DEBUG
xmlInitParser();
} // end of XmlInitParserLib
......@@ -63,6 +121,9 @@ void CloseXML2File(PGLOBAL g, PFBLOCK fp, bool all)
{
PX2BLOCK xp = (PX2BLOCK)fp;
if (trace)
htrc("CloseXML2File: xp=%p count=%d\n", xp, (xp) ? xp->Count : 0);
if (xp && xp->Count > 1 && !all) {
xp->Count--;
} else if (xp && xp->Count > 0) {
......@@ -101,6 +162,9 @@ bool LIBXMLDOC::Initialize(PGLOBAL g)
/******************************************************************/
bool LIBXMLDOC::ParseFile(char *fn)
{
if (trace)
htrc("ParseFile\n");
if ((Docp = xmlParseFile(fn))) {
if (Docp->encoding)
Encoding = (char*)Docp->encoding;
......@@ -149,6 +213,9 @@ bool LIBXMLDOC::NewDoc(PGLOBAL g, char *ver)
/******************************************************************/
void LIBXMLDOC::AddComment(PGLOBAL g, char *txtp)
{
if (trace)
htrc("AddComment: %s\n", txtp);
xmlNodePtr cp = xmlNewDocComment(Docp, BAD_CAST txtp);
xmlAddChild((xmlNodePtr)Docp, cp);
} // end of AddText
......@@ -158,6 +225,9 @@ void LIBXMLDOC::AddComment(PGLOBAL g, char *txtp)
/******************************************************************/
PXNODE LIBXMLDOC::GetRoot(PGLOBAL g)
{
if (trace)
htrc("GetRoot\n");
xmlNodePtr root = xmlDocGetRootElement(Docp);
if (!root)
......@@ -171,6 +241,9 @@ PXNODE LIBXMLDOC::GetRoot(PGLOBAL g)
/******************************************************************/
PXNODE LIBXMLDOC::NewRoot(PGLOBAL g, char *name)
{
if (trace)
htrc("NewRoot: %s\n", name);
xmlNodePtr root = xmlNewDocNode(Docp, NULL, BAD_CAST name, NULL);
if (root) {
......@@ -186,6 +259,9 @@ PXNODE LIBXMLDOC::NewRoot(PGLOBAL g, char *name)
/******************************************************************/
PXNODE LIBXMLDOC::NewPnode(PGLOBAL g, char *name)
{
if (trace)
htrc("NewNode: %s\n", name);
xmlNodePtr nop;
if (name) {
......@@ -224,6 +300,9 @@ int LIBXMLDOC::DumpDoc(PGLOBAL g, char *ofn)
int rc = 0;
FILE *of;
if (trace)
htrc("DumpDoc: %s\n", ofn);
if (!(of= global_fopen(g, MSGID_CANNOT_OPEN, ofn, "w")))
return -1;
......@@ -264,6 +343,9 @@ int LIBXMLDOC::DumpDoc(PGLOBAL g, char *ofn)
/******************************************************************/
void LIBXMLDOC::CloseDoc(PGLOBAL g, PFBLOCK xp)
{
if (trace)
htrc("CloseDoc: xp=%p count=%d\n", xp, (xp) ? xp->Count : 0);
if (xp && xp->Count == 1) {
if (Xop)
xmlXPathFreeObject(Xop);
......@@ -284,12 +366,18 @@ xmlNodeSetPtr LIBXMLDOC::GetNodeList(PGLOBAL g, xmlNodePtr np, char *xp)
xmlNodeSetPtr nl;
if (trace)
htrc("GetNodeList %s np=%p\n", xp, np);
htrc("GetNodeList: %s np=%p\n", xp, np);
if (!Ctxp) {
// Init Xpath
if (trace)
htrc("Calling xmlPathInit\n");
xmlXPathInit();
if (trace)
htrc("Calling xmlXPathNewContext Docp=%p\n", Docp);
// Create xpath evaluation context
if (!(Ctxp = xmlXPathNewContext(Docp))) {
strcpy(g->Message, MSG(XPATH_CNTX_ERR));
......@@ -301,7 +389,11 @@ xmlNodeSetPtr LIBXMLDOC::GetNodeList(PGLOBAL g, xmlNodePtr np, char *xp)
} // endif xpathCtx
// Register namespaces from list (if any)
for (PNS nsp = Namespaces; nsp; nsp = nsp->Next)
for (PNS nsp = Namespaces; nsp; nsp = nsp->Next) {
if (trace)
htrc("Calling xmlXPathRegisterNs Prefix=%s Uri=%s\n",
nsp->Prefix, nsp->Uri);
if (xmlXPathRegisterNs(Ctxp, BAD_CAST nsp->Prefix,
BAD_CAST nsp->Uri)) {
sprintf(g->Message, MSG(REGISTER_ERR), nsp->Prefix, nsp->Uri);
......@@ -312,12 +404,22 @@ xmlNodeSetPtr LIBXMLDOC::GetNodeList(PGLOBAL g, xmlNodePtr np, char *xp)
return NULL;
} // endif Registering
} else
xmlXPathFreeNodeSetList(Xop); // To be checked
} // endfor nsp
} else {
if (trace)
htrc("Calling xmlXPathFreeNodeSetList Xop=%p\n", Xop);
xmlXPathFreeObject(Xop);
// xmlXPathFreeNodeSetList(Xop); // Caused memory leak
} // endif Ctxp
// Set the context to the calling node
Ctxp->node = np;
if (trace)
htrc("Calling xmlXPathEval %s Ctxp=%p\n", xp, Ctxp);
// Evaluate table xpath
if (!(Xop = xmlXPathEval(BAD_CAST xp, Ctxp))) {
sprintf(g->Message, MSG(XPATH_EVAL_ERR), xp);
......@@ -439,6 +541,9 @@ int XML2NODE::GetType(void)
/******************************************************************/
PXNODE XML2NODE::GetNext(PGLOBAL g)
{
if (trace)
htrc("GetNext\n");
if (!Nodep->next)
Next = NULL;
else if (!Next)
......@@ -452,6 +557,9 @@ PXNODE XML2NODE::GetNext(PGLOBAL g)
/******************************************************************/
PXNODE XML2NODE::GetChild(PGLOBAL g)
{
if (trace)
htrc("GetChild\n");
if (!Nodep->children)
Children = NULL;
else if (!Children)
......@@ -467,6 +575,9 @@ RCODE XML2NODE::GetContent(PGLOBAL g, char *buf, int len)
{
RCODE rc = RC_OK;
if (trace)
htrc("GetContent\n");
if (Content)
xmlFree(Content);
......@@ -505,18 +616,24 @@ RCODE XML2NODE::GetContent(PGLOBAL g, char *buf, int len)
} else
*buf = '\0';
if (trace)
htrc("GetContent: %s\n", buf);
return rc;
} // end of GetText
} // end of GetContent
/******************************************************************/
/* Set the content of a node. */
/******************************************************************/
bool XML2NODE::SetContent(PGLOBAL g, char *txtp, int len)
{
if (trace)
htrc("SetContent: %s\n", txtp);
xmlChar *buf = xmlEncodeEntitiesReentrant(Docp, BAD_CAST txtp);
if (trace)
htrc("SetContent %s -> %s\n", txtp, buf);
htrc("SetContent: %s -> %s\n", txtp, buf);
xmlNodeSetContent(Nodep, buf);
xmlFree(buf);
......@@ -528,6 +645,9 @@ bool XML2NODE::SetContent(PGLOBAL g, char *txtp, int len)
/******************************************************************/
PXNODE XML2NODE::Clone(PGLOBAL g, PXNODE np)
{
if (trace)
htrc("Clone: np=%p\n", np);
if (np) {
((PNODE2)np)->Nodep = Nodep;
return np;
......@@ -542,7 +662,7 @@ PXNODE XML2NODE::Clone(PGLOBAL g, PXNODE np)
PXLIST XML2NODE::GetChildElements(PGLOBAL g, char *xp, PXLIST lp)
{
if (trace)
htrc("GetChildElements %s\n", xp);
htrc("GetChildElements: %s\n", xp);
return SelectNodes(g, (xp) ? xp : (char*)"*", lp);
} // end of GetChildElements
......@@ -553,7 +673,7 @@ PXLIST XML2NODE::GetChildElements(PGLOBAL g, char *xp, PXLIST lp)
PXLIST XML2NODE::SelectNodes(PGLOBAL g, char *xp, PXLIST lp)
{
if (trace)
htrc("SelectNodes %s\n", xp);
htrc("SelectNodes: %s\n", xp);
xmlNodeSetPtr nl = ((PXDOC2)Doc)->GetNodeList(g, Nodep, xp);
......@@ -571,7 +691,7 @@ PXLIST XML2NODE::SelectNodes(PGLOBAL g, char *xp, PXLIST lp)
PXNODE XML2NODE::SelectSingleNode(PGLOBAL g, char *xp, PXNODE np)
{
if (trace)
htrc("SelectSingleNode %s\n", xp);
htrc("SelectSingleNode: %s\n", xp);
xmlNodeSetPtr nl = ((PXDOC2)Doc)->GetNodeList(g, Nodep, xp);
......@@ -593,7 +713,7 @@ PXNODE XML2NODE::SelectSingleNode(PGLOBAL g, char *xp, PXNODE np)
PXATTR XML2NODE::GetAttribute(PGLOBAL g, char *name, PXATTR ap)
{
if (trace)
htrc("GetAttribute %s\n", name);
htrc("GetAttribute: %s\n", name);
xmlAttrPtr atp = xmlHasProp(Nodep, BAD_CAST name);
......@@ -618,7 +738,7 @@ PXNODE XML2NODE::AddChildNode(PGLOBAL g, char *name, PXNODE np)
char *p, *pn, *pf = NULL;
if (trace)
htrc("AddChildNode %s\n", name);
htrc("AddChildNode: %s\n", name);
// Is a prefix specified
if ((pn = strchr(name, ':'))) {
......@@ -669,7 +789,7 @@ PXNODE XML2NODE::AddChildNode(PGLOBAL g, char *name, PXNODE np)
PXATTR XML2NODE::AddProperty(PGLOBAL g, char *name, PXATTR ap)
{
if (trace)
htrc("AddProperty %s\n", name);
htrc("AddProperty: %s\n", name);
xmlAttrPtr atp = xmlNewProp(Nodep, BAD_CAST name, NULL);
......@@ -692,7 +812,7 @@ PXATTR XML2NODE::AddProperty(PGLOBAL g, char *name, PXATTR ap)
void XML2NODE::AddText(PGLOBAL g, char *txtp)
{
if (trace)
htrc("AddText %s\n", txtp);
htrc("AddText: %s\n", txtp);
// This is to avoid a blank line when inserting a new line
xmlNodePtr np = xmlGetLastChild(Nodep);
......@@ -711,6 +831,9 @@ void XML2NODE::AddText(PGLOBAL g, char *txtp)
/******************************************************************/
void XML2NODE::DeleteChild(PGLOBAL g, PXNODE dnp)
{
if (trace)
htrc("DeleteChild: node=%p\n", dnp);
xmlNodePtr np = ((PNODE2)dnp)->Nodep;
xmlNodePtr text = np->next;
......@@ -750,7 +873,7 @@ int XML2NODELIST::GetLength(void)
PXNODE XML2NODELIST::GetItem(PGLOBAL g, int n, PXNODE np)
{
if (trace)
htrc("GetItem %d\n", n);
htrc("GetItem: %d\n", n);
if (!Listp || Listp->nodeNr <= n)
return NULL;
......@@ -781,7 +904,7 @@ XML2ATTR::XML2ATTR(PXDOC dp, xmlAttrPtr ap, xmlNodePtr np)
bool XML2ATTR::SetText(PGLOBAL g, char *txtp, int len)
{
if (trace)
htrc("SetText %s %d\n", txtp, len);
htrc("SetText: %s %d\n", txtp, len);
xmlSetProp(Parent, Atrp->name, BAD_CAST txtp);
return false;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment