summaryrefslogtreecommitdiff
path: root/storage
diff options
context:
space:
mode:
authorOlivier Bertrand <bertrandop@gmail.com>2013-07-02 00:07:48 +0200
committerOlivier Bertrand <bertrandop@gmail.com>2013-07-02 00:07:48 +0200
commit37fce46f6605160734ba3a5d69fb653b0cdd28c5 (patch)
treeb32706553fed110265539b4e0e407792164a620f /storage
parent29f10f0ff19f245a7e00e8ece8a477c1d8bf4a01 (diff)
downloadmariadb-git-37fce46f6605160734ba3a5d69fb653b0cdd28c5.tar.gz
- Fix memory leak in libdoc.cpp in LIBXMLDOC::GetNodeList replacing
xmlXPathFreeNodeSetList(Xop); // Caused memory leak, by xmlXPathFreeObject(Xop); modified: storage/connect/libdoc.cpp
Diffstat (limited to 'storage')
-rw-r--r--storage/connect/libdoc.cpp153
1 files changed, 138 insertions, 15 deletions
diff --git a/storage/connect/libdoc.cpp b/storage/connect/libdoc.cpp
index 95b98931680..2a786ef0eef 100644
--- a/storage/connect/libdoc.cpp
+++ b/storage/connect/libdoc.cpp
@@ -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;