From 8585a6b58654610839139653e7793d7e6e485199 Mon Sep 17 00:00:00 2001
From: Olivier Bertrand <bertrandop@gmail.com>
Date: Sat, 27 Sep 2014 12:09:37 +0200
Subject: [PATCH] - Fix: Crash of an XCOL table when the Colname column size is
 too small.   Was because of buffer overrun in XCLCOL::ReadColumn.   The Cbuf
 buffer was unconditionally filled Now it is limited to its size.   This
 happened because this buffer was allocated according to the XCOL   column
 size. It is now allocated according to the source column size. modified:  
 storage/connect/plgdbsem.h   storage/connect/tabutil.h  
 storage/connect/tabxcl.cpp   storage/connect/tabxcl.h

---
 storage/connect/plgdbsem.h |  2 +-
 storage/connect/tabutil.h  |  2 +-
 storage/connect/tabxcl.cpp | 20 +++++++++++++++++---
 storage/connect/tabxcl.h   |  1 +
 4 files changed, 20 insertions(+), 5 deletions(-)

diff --git a/storage/connect/plgdbsem.h b/storage/connect/plgdbsem.h
index 7d5931285c..ef209a9b8b 100644
--- a/storage/connect/plgdbsem.h
+++ b/storage/connect/plgdbsem.h
@@ -582,7 +582,7 @@ DllExport void   *PlgDBSubAlloc(PGLOBAL g, void *memp, size_t size);
 DllExport void   *PlgDBalloc(PGLOBAL, void *, MBLOCK&);
 DllExport void   *PlgDBrealloc(PGLOBAL, void *, MBLOCK&, size_t);
 DllExport void    NewPointer(PTABS, void *, void *);
-DllExport char    *GetIni(int n= 0);
+//lExport char   *GetIni(int n= 0);    // Not used anymore
 DllExport void    SetTrc(void);
 DllExport char   *GetListOption(PGLOBAL, const char *, const char *,
                                          const char *def=NULL);
diff --git a/storage/connect/tabutil.h b/storage/connect/tabutil.h
index 11f18be074..606e532d52 100644
--- a/storage/connect/tabutil.h
+++ b/storage/connect/tabutil.h
@@ -114,7 +114,7 @@ class DllExport PRXCOL : public COLBLK {
                 {return false;}
   virtual void ReadColumn(PGLOBAL g);
   virtual void WriteColumn(PGLOBAL g);
-          bool Init(PGLOBAL g, PTDBASE tp = NULL);
+  virtual bool Init(PGLOBAL g, PTDBASE tp = NULL);
 
  protected:
   // Default constructor not to be used
diff --git a/storage/connect/tabxcl.cpp b/storage/connect/tabxcl.cpp
index bd3d57257f..66e2577056 100644
--- a/storage/connect/tabxcl.cpp
+++ b/storage/connect/tabxcl.cpp
@@ -184,7 +184,7 @@ bool TDBXCL::OpenDB(PGLOBAL g)
   /*  Check and initialize the subtable columns.                       */
   /*********************************************************************/
   for (PCOL cp = Columns; cp; cp = cp->GetNext())
-    if (((PXCLCOL)cp)->Init(g))
+    if (((PPRXCOL)cp)->Init(g))
       return TRUE;
 
   /*********************************************************************/
@@ -240,12 +240,25 @@ XCLCOL::XCLCOL(PGLOBAL g, PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i)
 			: PRXCOL(cdp, tdbp, cprec, i, "XCL")
   {
   // Set additional XXL access method information for column.
-  Cbuf = (char*)PlugSubAlloc(g, NULL, Long + 1);
+  Cbuf = NULL;                // Will be allocated later
 	Cp = NULL;						      // Pointer to current position in Cbuf
 	Sep = ((PTDBXCL)tdbp)->Sep;
 	AddStatus(BUF_READ);	      // Only evaluated from TDBXCL::ReadDB
   } // end of XCLCOL constructor
 
+/***********************************************************************/
+/*  XCLCOL initialization routine.                                     */
+/*  Allocate Cbuf that will contain the Colp value.                    */
+/***********************************************************************/
+bool XCLCOL::Init(PGLOBAL g, PTDBASE tp)
+  {
+  if (PRXCOL::Init(g, tp))
+    return true;
+
+  Cbuf = (char*)PlugSubAlloc(g, NULL, Colp->GetLength() + 1);
+  return false;
+  } // end of Init
+
 /***********************************************************************/
 /*  What this routine does is to get the comma-separated string        */
 /*  from the source table column, extract the single values and        */
@@ -255,7 +268,8 @@ void XCLCOL::ReadColumn(PGLOBAL g)
   {
 	if (((PTDBXCL)To_Tdb)->New) {
 		Colp->Eval(g);
-		strcpy(Cbuf, To_Val->GetCharValue());
+		strncpy(Cbuf, To_Val->GetCharValue(), Colp->GetLength());
+    Cbuf[Colp->GetLength()] = 0;
 		Cp = Cbuf;
 		} // endif New
 
diff --git a/storage/connect/tabxcl.h b/storage/connect/tabxcl.h
index 2412257310..05118c5dd2 100644
--- a/storage/connect/tabxcl.h
+++ b/storage/connect/tabxcl.h
@@ -90,6 +90,7 @@ class XCLCOL : public PRXCOL {
   // Methods
   virtual void Reset(void) {Colp->Reset();}	// Evaluated only by TDBXCL
   virtual void ReadColumn(PGLOBAL g);
+  virtual bool Init(PGLOBAL g, PTDBASE tp = NULL);
 
  protected:
   // Default constructor not to be used
-- 
2.30.9