summaryrefslogtreecommitdiff
path: root/storage
diff options
context:
space:
mode:
authorOlivier Bertrand <bertrandop@gmail.com>2013-09-22 13:40:31 +0200
committerOlivier Bertrand <bertrandop@gmail.com>2013-09-22 13:40:31 +0200
commit65b0e5455b547a3d574fa77b34cce23ae3bea0a0 (patch)
treec9d9d63f7fe6c031b16a8ddaec4fc8fa969ec2d6 /storage
parentbd37d644d6a93e595d98ec20172cad527c3e23bd (diff)
downloadmariadb-git-65b0e5455b547a3d574fa77b34cce23ae3bea0a0.tar.gz
- Fix several bugs causing memory leak or invalid access detected
by Valgrind. This concerns the XML libxml2 support. modified: storage/connect/domdoc.cpp storage/connect/domdoc.h storage/connect/ha_connect.cc storage/connect/libdoc.cpp storage/connect/plgdbsem.h storage/connect/plgxml.h storage/connect/tabxml.cpp storage/connect/tabxml.h
Diffstat (limited to 'storage')
-rw-r--r--storage/connect/domdoc.cpp12
-rw-r--r--storage/connect/domdoc.h3
-rw-r--r--storage/connect/ha_connect.cc8
-rw-r--r--storage/connect/libdoc.cpp169
-rw-r--r--storage/connect/plgdbsem.h1
-rw-r--r--storage/connect/plgxml.h1
-rw-r--r--storage/connect/tabxml.cpp38
-rw-r--r--storage/connect/tabxml.h4
8 files changed, 191 insertions, 45 deletions
diff --git a/storage/connect/domdoc.cpp b/storage/connect/domdoc.cpp
index ebdaeba57b5..0272a1d709a 100644
--- a/storage/connect/domdoc.cpp
+++ b/storage/connect/domdoc.cpp
@@ -592,6 +592,18 @@ PXNODE DOMNODELIST::GetItem(PGLOBAL g, int n, PXNODE np)
} // end of GetItem
+/******************************************************************/
+/* Reset the pointer on the deleted item. */
+/******************************************************************/
+bool DOMNODELIST::DropItem(PGLOBAL g, int n)
+ {
+ if (Listp == NULL || Listp->length <= n)
+ return true;
+
+//Listp->item[n] = NULL; La propriété n'a pas de méthode 'set'
+ return false;
+ } // end of DeleteItem
+
/* ----------------------- class DOMATTR ------------------------ */
/******************************************************************/
diff --git a/storage/connect/domdoc.h b/storage/connect/domdoc.h
index 0fd0a58ffdb..b0bcc1478a5 100644
--- a/storage/connect/domdoc.h
+++ b/storage/connect/domdoc.h
@@ -104,8 +104,9 @@ class DOMNODELIST : public XMLNODELIST {
friend class DOMNODE;
public:
// Methods
- virtual int GetLength(void) {return Listp->length;}
+ virtual int GetLength(void) {return Listp->length;}
virtual PXNODE GetItem(PGLOBAL g, int n, PXNODE np);
+ virtual bool DropItem(PGLOBAL g, int n);
protected:
// Constructor
diff --git a/storage/connect/ha_connect.cc b/storage/connect/ha_connect.cc
index bca4a6efc73..a44310fd52b 100644
--- a/storage/connect/ha_connect.cc
+++ b/storage/connect/ha_connect.cc
@@ -1093,7 +1093,8 @@ PTDB ha_connect::GetTDB(PGLOBAL g)
if (!xp->CheckQuery(valid_query_id) && tdbp
&& !stricmp(tdbp->GetName(), table_name)
- && tdbp->GetMode() == xmod) {
+ && (tdbp->GetMode() == xmod
+ || tdbp->GetAmType() == TYPE_AM_XML)) {
tp= tdbp;
tp->SetMode(xmod);
} else if ((tp= CntGetTDB(g, table_name, xmod, this)))
@@ -2658,8 +2659,9 @@ int ha_connect::delete_all_rows()
PGLOBAL g= xp->g;
DBUG_ENTER("ha_connect::delete_all_rows");
- // Close and reopen the table so it will be deleted
- rc= CloseTable(g);
+ if (tdbp && tdbp->GetAmType() != TYPE_AM_XML)
+ // Close and reopen the table so it will be deleted
+ rc= CloseTable(g);
if (!(OpenTable(g))) {
if (CntDeleteRow(g, tdbp, true)) {
diff --git a/storage/connect/libdoc.cpp b/storage/connect/libdoc.cpp
index 45f379350f5..01a9f858fb0 100644
--- a/storage/connect/libdoc.cpp
+++ b/storage/connect/libdoc.cpp
@@ -14,6 +14,10 @@
#include "my_global.h"
//#endif // !WIN32
+#if !defined(LIBXML_TREE_ENABLED) || !defined(LIBXML_OUTPUT_ENABLED)
+#error "tree support not compiled in"
+#endif
+
#if !defined(LIBXML_XPATH_ENABLED) || !defined(LIBXML_SAX1_ENABLED)
#error "XPath not supported"
#endif
@@ -47,8 +51,6 @@ typedef struct _x2block { /* Loaded XML file block */
short Type; /* TYPE_FB_XML */
int Retcode; /* Return code from Load */
xmlDocPtr Docp; /* Document interface pointer */
-// xmlXPathContextPtr Ctxp;
-// xmlXPathObjectPtr Xop;
} X2BLOCK, *PX2BLOCK;
/******************************************************************/
@@ -91,6 +93,8 @@ class LIBXMLDOC : public XMLDOCUMENT {
xmlNodeSetPtr Nlist;
xmlXPathContextPtr Ctxp;
xmlXPathObjectPtr Xop;
+ xmlXPathObjectPtr NlXop;
+ xmlErrorPtr Xerr;
char *Buf; // Temporary
bool Nofreelist;
}; // end of class LIBXMLDOC
@@ -141,6 +145,7 @@ class XML2NODELIST : public XMLNODELIST {
// Methods
virtual int GetLength(void);
virtual PXNODE GetItem(PGLOBAL g, int n, PXNODE np);
+ virtual bool DropItem(PGLOBAL g, int n);
protected:
// Constructor
@@ -180,6 +185,23 @@ extern int trace;
} // "C"
#if defined(MEMORY_TRACE)
+static int m = 0;
+static char s[500];
+/**************************************************************************/
+/* Tracing output function. */
+/**************************************************************************/
+void xtrc(char const *fmt, ...)
+ {
+ va_list ap;
+ va_start (ap, fmt);
+
+//vfprintf(stderr, fmt, ap);
+ vsprintf(s, fmt, ap);
+ if (s[strlen(s)-1] == '\n')
+ s[strlen(s)-1] = 0;
+ va_end (ap);
+ } // end of htrc
+
static xmlFreeFunc Free;
static xmlMallocFunc Malloc;
static xmlMallocFunc MallocA;
@@ -188,42 +210,53 @@ static xmlStrdupFunc Strdup;
void xmlMyFree(void *mem)
{
- if (trace)
- htrc("Freeing at %p\n", mem);
+ if (trace) {
+ htrc("%.4d Freeing at %p %s\n", ++m, mem, s);
+ *s = 0;
+ } // endif trace
Free(mem);
} // end of xmlMyFree
void *xmlMyMalloc(size_t size)
{
void *p = Malloc(size);
- if (trace)
- htrc("Allocating %.5d at %p\n", size, p);
+ if (trace) {
+ htrc("%.4d Allocating %.5d at %p %s\n", ++m, size, p, s);
+ *s = 0;
+ } // endif trace
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);
+ if (trace) {
+ htrc("%.4d Atom alloc %.5d at %p %s\n", ++m, size, p, s);
+ *s = 0;
+ } // endif trace
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);
+ if (trace) {
+ htrc("%.4d ReAlloc %.5d to %p from %p %s\n", ++m, size, p, mem, s);
+ *s = 0;
+ } // endif trace
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);
+ if (trace) {
+ htrc("%.4d Duplicating to %p from %p %s %s\n", ++m, p, str, str, s);
+ *s = 0;
+ } // endif trace
return p;
} // end of xmlMyStrdup
+#define htrc xtrc
#endif // MEMORY_TRACE
/******************************************************************/
@@ -295,6 +328,8 @@ LIBXMLDOC::LIBXMLDOC(char *nsl, char *nsdf, char *enc, PFBLOCK fp)
Nlist = NULL;
Ctxp = NULL;
Xop = NULL;
+ NlXop = NULL;
+ Xerr = NULL;
Buf = NULL;
Nofreelist = false;
} // end of LIBXMLDOC constructor
@@ -321,9 +356,10 @@ bool LIBXMLDOC::ParseFile(char *fn)
Encoding = (char*)Docp->encoding;
return false;
- } else
- return true;
+ } else if ((Xerr = xmlGetLastError()))
+ xmlResetError(Xerr);
+ return true;
} // end of ParseFile
/******************************************************************/
@@ -344,8 +380,6 @@ PFBLOCK LIBXMLDOC::LinkXblock(PGLOBAL g, MODE m, int rc, char *fn)
xp->Length = (m == MODE_READ) ? 1 : 0;
xp->Retcode = rc;
xp->Docp = Docp;
-// xp->Ctxp = Ctxp;
-// xp->Xop = Xop;
// Return xp as a fp
return (PFBLOCK)xp;
@@ -356,6 +390,9 @@ PFBLOCK LIBXMLDOC::LinkXblock(PGLOBAL g, MODE m, int rc, char *fn)
/******************************************************************/
bool LIBXMLDOC::NewDoc(PGLOBAL g, char *ver)
{
+ if (trace)
+ htrc("NewDoc\n");
+
return ((Docp = xmlNewDoc(BAD_CAST ver)) == NULL);
} // end of NewDoc
@@ -462,8 +499,7 @@ int LIBXMLDOC::DumpDoc(PGLOBAL g, char *ofn)
if (xmlSaveFormatFileEnc((const char *)ofn, Docp, Encoding, 0) < 0) {
xmlErrorPtr err = xmlGetLastError();
- strcpy(g->Message, (err) ? err->message : "Error saving XML doc"
- );
+ strcpy(g->Message, (err) ? err->message : "Error saving XML doc");
rc = -1;
} // endif Save
// rc = xmlDocDump(of, Docp);
@@ -497,17 +533,40 @@ 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 (Nlist)
+//if (xp && xp->Count == 1) {
+ if (Nlist) {
xmlXPathFreeNodeSet(Nlist);
- if (Xop)
+ if ((Xerr = xmlGetLastError()))
+ xmlResetError(Xerr);
+
+ } // endif Nlist
+
+ if (Xop) {
xmlXPathFreeObject(Xop);
- if (Ctxp)
+ if ((Xerr = xmlGetLastError()))
+ xmlResetError(Xerr);
+
+ } // endif Xop
+
+ if (NlXop) {
+ xmlXPathFreeObject(NlXop);
+
+ if ((Xerr = xmlGetLastError()))
+ xmlResetError(Xerr);
+
+ } // endif NlXop
+
+ if (Ctxp) {
xmlXPathFreeContext(Ctxp);
- } // endif Count
+ if ((Xerr = xmlGetLastError()))
+ xmlResetError(Xerr);
+
+ } // endif Ctxp
+
+// } // endif Count
CloseXML2File(g, xp, false);
} // end of Close
@@ -560,18 +619,29 @@ xmlNodeSetPtr LIBXMLDOC::GetNodeList(PGLOBAL g, xmlNodePtr np, char *xp)
} // endfor nsp
- } else {
+ } // endif Ctxp
+
+ if (Xop) {
if (trace)
- htrc("Calling xmlXPathFreeNodeSetList Xop=%p\n", Xop);
+ htrc("Calling xmlXPathFreeNodeSetList Xop=%p NOFREE=%d\n",
+ Xop, Nofreelist);
if (Nofreelist) {
// Making Nlist that must not be freed yet
- xmlXPathFreeNodeSetList(Xop); // Caused memory leak
+// xmlXPathFreeNodeSetList(Xop); // Caused memory leak
+ assert(!NlXop);
+ NlXop = Xop; // Freed on closing
Nofreelist = false;
} else
xmlXPathFreeObject(Xop); // Caused node not found
- } // endif Ctxp
+ if ((Xerr = xmlGetLastError())) {
+ strcpy(g->Message, Xerr->message);
+ xmlResetError(Xerr);
+ return NULL;
+ } // endif Xerr
+
+ } // endif Xop
// Set the context to the calling node
Ctxp->node = np;
@@ -990,6 +1060,8 @@ void XML2NODE::AddText(PGLOBAL g, char *txtp)
/******************************************************************/
void XML2NODE::DeleteChild(PGLOBAL g, PXNODE dnp)
{
+ xmlErrorPtr xerr;
+
if (trace)
htrc("DeleteChild: node=%p\n", dnp);
@@ -999,12 +1071,39 @@ void XML2NODE::DeleteChild(PGLOBAL g, PXNODE dnp)
// This is specific to row nodes
if (text && text->type == XML_TEXT_NODE) {
xmlUnlinkNode(text);
+
+ if ((xerr = xmlGetLastError()))
+ goto err;
+
xmlFreeNode(text);
+
+ if ((xerr = xmlGetLastError()))
+ goto err;
+
} // endif type
xmlUnlinkNode(np);
+
+ if ((xerr = xmlGetLastError()))
+ goto err;
+
xmlFreeNode(np);
+
+ if ((xerr = xmlGetLastError()))
+ goto err;
+
Delete(dnp);
+
+ if ((xerr = xmlGetLastError()))
+ goto err;
+
+ return;
+
+err:
+ if (trace)
+ htrc("DeleteChild: errmsg=%s\n", xerr->message);
+
+ xmlResetError(xerr);
} // end of DeleteChild
/* -------------------- class XML2NODELIST ---------------------- */
@@ -1045,6 +1144,22 @@ PXNODE XML2NODELIST::GetItem(PGLOBAL g, int n, PXNODE np)
} // end of GetItem
+/******************************************************************/
+/* Reset the pointer on the deleted item. */
+/******************************************************************/
+bool XML2NODELIST::DropItem(PGLOBAL g, int n)
+ {
+ if (trace)
+ htrc("DropItem: n=%d\n", n);
+
+ // We should do something here
+ if (!Listp || Listp->nodeNr <= n)
+ return true;
+
+ Listp->nodeTab[n] = NULL; // This was causing Valgrind warning
+ return false;
+ } // end of DropItem
+
/* ---------------------- class XML2ATTR ------------------------ */
/******************************************************************/
diff --git a/storage/connect/plgdbsem.h b/storage/connect/plgdbsem.h
index 11fe5694bc6..0d2dfde3eb3 100644
--- a/storage/connect/plgdbsem.h
+++ b/storage/connect/plgdbsem.h
@@ -111,6 +111,7 @@ enum AMT {TYPE_AM_ERROR = 0, /* Type not defined */
TYPE_AM_PIVOT = 120, /* PIVOT access method type no */
TYPE_AM_SRC = 121, /* PIVOT multiple column type no */
TYPE_AM_FNC = 122, /* PIVOT source column type no */
+ TYPE_AM_XML = 127, /* XML access method type no */
TYPE_AM_XTB = 130, /* SYS table access method type */
TYPE_AM_MAC = 137, /* MAC table access method type */
TYPE_AM_WMI = 139, /* WMI table access method type */
diff --git a/storage/connect/plgxml.h b/storage/connect/plgxml.h
index b8352c36c14..74a16fd4823 100644
--- a/storage/connect/plgxml.h
+++ b/storage/connect/plgxml.h
@@ -147,6 +147,7 @@ class XMLNODELIST : public BLOCK {
// Properties
virtual int GetLength(void) = 0;
virtual PXNODE GetItem(PGLOBAL, int, PXNODE = NULL) = 0;
+ virtual bool DropItem(PGLOBAL, int) = 0;
protected:
// Constructor
diff --git a/storage/connect/tabxml.cpp b/storage/connect/tabxml.cpp
index 69ad6711638..3feba14ca5e 100644
--- a/storage/connect/tabxml.cpp
+++ b/storage/connect/tabxml.cpp
@@ -78,7 +78,9 @@ XMLDEF::XMLDEF(void)
DefNs = NULL;
Attrib = NULL;
Hdattr = NULL;
+ Coltype = 1;
Limit = 0;
+ Header = 0;
Xpand = false;
Usedom = false;
} // end of XMLDEF constructor
@@ -338,17 +340,14 @@ PCOL TDBXML::InsertSpecialColumn(PGLOBAL g, PCOL colp)
/***********************************************************************/
/* LoadTableFile: Load and parse an XML file. */
/***********************************************************************/
-int TDBXML::LoadTableFile(PGLOBAL g)
+int TDBXML::LoadTableFile(PGLOBAL g, char *filename)
{
- char filename[_MAX_PATH];
int rc = RC_OK, type = (Usedom) ? TYPE_FB_XML : TYPE_FB_XML2;
PFBLOCK fp = NULL;
PDBUSER dup = (PDBUSER)g->Activityp->Aptr;
- /*********************************************************************/
- /* We used the file name relative to recorded datapath. */
- /*********************************************************************/
- PlugSetPath(filename, Xfile, GetPath());
+ if (Docp)
+ return rc; // Already done
if (trace)
htrc("TDBXML: loading %s\n", filename);
@@ -397,6 +396,7 @@ int TDBXML::LoadTableFile(PGLOBAL g)
} else
rc = (errno == ENOENT) ? RC_NF : RC_INFO;
+ // Cannot make a Xblock until document is made
return rc;
} // endif Docp
@@ -418,9 +418,8 @@ int TDBXML::LoadTableFile(PGLOBAL g)
/***********************************************************************/
bool TDBXML::Initialize(PGLOBAL g)
{
- char tabpath[64];
- int rc;
- PXMLCOL colp;
+ int rc;
+ PXMLCOL colp;
if (Void)
return false;
@@ -440,8 +439,13 @@ bool TDBXML::Initialize(PGLOBAL g)
#else
if (!Root) {
#endif
+ char tabpath[64], filename[_MAX_PATH];
+
+ // We used the file name relative to recorded datapath
+ PlugSetPath(filename, Xfile, GetPath());
+
// Load or re-use the table file
- rc = LoadTableFile(g);
+ rc = LoadTableFile(g, filename);
if (rc == RC_OK) {
// Get root node
@@ -503,6 +507,9 @@ bool TDBXML::Initialize(PGLOBAL g)
goto error;
} // endif NewDoc
+ // Now we can link the Xblock
+ To_Xb = Docp->LinkXblock(g, Mode, rc, filename);
+
// Add a CONNECT comment node
// sprintf(buf, MSG(CREATED_PLUGDB), version);
sprintf(buf, " Created by CONNECT %s ", version);
@@ -893,12 +900,21 @@ int TDBXML::DeleteDB(PGLOBAL g, int irc)
if ((RowNode = Nlist->GetItem(g, Irow, RowNode)) == NULL) {
sprintf(g->Message, MSG(MISSING_ROWNODE), Irow);
return RC_FX;
- } else
+ } else {
TabNode->DeleteChild(g, RowNode);
+ if (Nlist->DropItem(g, Irow))
+ return RC_FX;
+
+ } // endif RowNode
+
Changed = true;
} else if (irc != RC_EF) {
TabNode->DeleteChild(g, RowNode);
+
+ if (Nlist->DropItem(g, Irow))
+ return RC_FX;
+
Changed = true;
} // endif's irc
diff --git a/storage/connect/tabxml.h b/storage/connect/tabxml.h
index 1bce0824e49..5aa038530c7 100644
--- a/storage/connect/tabxml.h
+++ b/storage/connect/tabxml.h
@@ -6,8 +6,6 @@
/* */
/* This file contains the XML table classes declares. */
/***********************************************************************/
-#define TYPE_AM_XML (AMT)127
-
typedef class XMLDEF *PXMLDEF;
typedef class TDBXML *PTDBXML;
typedef class XMLCOL *PXMLCOL;
@@ -81,7 +79,7 @@ class DllExport TDBXML : public TDBASE {
virtual void ResetDB(void) {N = 0;}
virtual void ResetSize(void) {MaxSize = -1;}
virtual int RowNumber(PGLOBAL g, bool b = false);
- int LoadTableFile(PGLOBAL g);
+ int LoadTableFile(PGLOBAL g, char *filename);
bool Initialize(PGLOBAL g);
bool SetTabNode(PGLOBAL g);
void SetNodeAttr(PGLOBAL g, char *attr, PXNODE node);