summaryrefslogtreecommitdiff
path: root/storage/connect
diff options
context:
space:
mode:
Diffstat (limited to 'storage/connect')
-rw-r--r--storage/connect/catalog.h4
-rw-r--r--storage/connect/mysql-test/connect/r/mysql.result11
-rw-r--r--storage/connect/mysql-test/connect/t/mysql.test15
-rw-r--r--storage/connect/myutil.cpp2
-rw-r--r--storage/connect/reldef.cpp26
-rw-r--r--storage/connect/tabbson.cpp47
-rw-r--r--storage/connect/tabdos.cpp61
-rw-r--r--storage/connect/tabext.cpp57
-rw-r--r--storage/connect/tabfmt.cpp38
-rw-r--r--storage/connect/tabjdbc.cpp45
-rw-r--r--storage/connect/tabjson.cpp54
-rw-r--r--storage/connect/value.cpp8
-rw-r--r--storage/connect/value.h2
13 files changed, 213 insertions, 157 deletions
diff --git a/storage/connect/catalog.h b/storage/connect/catalog.h
index 2649a50cf76..a46615f5d6e 100644
--- a/storage/connect/catalog.h
+++ b/storage/connect/catalog.h
@@ -39,9 +39,9 @@ typedef struct _colinfo {
PCSZ Name;
int Type;
int Offset;
- int Length;
+ unsigned Length;
int Key;
- int Precision;
+ unsigned Precision;
int Scale;
int Opt;
int Freq;
diff --git a/storage/connect/mysql-test/connect/r/mysql.result b/storage/connect/mysql-test/connect/r/mysql.result
index d3c244b277a..1dcbca88a7b 100644
--- a/storage/connect/mysql-test/connect/r/mysql.result
+++ b/storage/connect/mysql-test/connect/r/mysql.result
@@ -364,5 +364,16 @@ hex(col)
DROP TABLE t2;
DROP TABLE t1;
#
+# MDEV-29782 CONNECT engine converted YEAR to DATETIME, causing INSERT to fail
+#
+CREATE TABLE t1 (id year);
+CREATE TABLE t2 ENGINE=CONNECT TABLE_TYPE=MYSQL DBNAME='test' TABNAME='t1' OPTION_LIST='host=localhost,user=root,port=PORT';
+INSERT INTO t2 VALUES (1999);
+SELECT * FROM t2;
+id
+1999
+DROP TABLE t2;
+DROP TABLE t1;
+#
# End of 10.3 tests
#
diff --git a/storage/connect/mysql-test/connect/t/mysql.test b/storage/connect/mysql-test/connect/t/mysql.test
index a50db4a6457..cd52f78fb30 100644
--- a/storage/connect/mysql-test/connect/t/mysql.test
+++ b/storage/connect/mysql-test/connect/t/mysql.test
@@ -534,5 +534,20 @@ DROP TABLE t1;
--echo #
+--echo # MDEV-29782 CONNECT engine converted YEAR to DATETIME, causing INSERT to fail
+--echo #
+
+CREATE TABLE t1 (id year);
+
+--replace_result $PORT PORT
+--eval CREATE TABLE t2 ENGINE=CONNECT TABLE_TYPE=MYSQL DBNAME='test' TABNAME='t1' OPTION_LIST='host=localhost,user=root,port=$PORT'
+
+INSERT INTO t2 VALUES (1999);
+SELECT * FROM t2;
+
+DROP TABLE t2;
+DROP TABLE t1;
+
+--echo #
--echo # End of 10.3 tests
--echo #
diff --git a/storage/connect/myutil.cpp b/storage/connect/myutil.cpp
index c49db48bfb3..45b2c46e217 100644
--- a/storage/connect/myutil.cpp
+++ b/storage/connect/myutil.cpp
@@ -183,6 +183,7 @@ int MYSQLtoPLG(int mytype, char *var)
switch (mytype) {
case MYSQL_TYPE_SHORT:
+ case MYSQL_TYPE_YEAR:
type = TYPE_SHORT;
break;
case MYSQL_TYPE_LONG:
@@ -209,7 +210,6 @@ int MYSQLtoPLG(int mytype, char *var)
case MYSQL_TYPE_TIMESTAMP:
case MYSQL_TYPE_DATE:
case MYSQL_TYPE_DATETIME:
- case MYSQL_TYPE_YEAR:
case MYSQL_TYPE_TIME:
type = TYPE_DATE;
break;
diff --git a/storage/connect/reldef.cpp b/storage/connect/reldef.cpp
index 114071b35fb..9af9faa333a 100644
--- a/storage/connect/reldef.cpp
+++ b/storage/connect/reldef.cpp
@@ -91,11 +91,11 @@ PQRYRES OEMColumns(PGLOBAL g, PTOS topt, char* tab, char* db, bool info)
/* directories are used (to make this even remotely secure). */
/*********************************************************************/
if (check_valid_path(module, strlen(module))) {
- strcpy(g->Message, "Module cannot contain a path");
+ safe_strcpy(g->Message, sizeof(g->Message), "Module cannot contain a path");
return NULL;
}
else if (strlen(subtype)+1+3 >= sizeof(getname)) {
- strcpy(g->Message, "Subtype string too long");
+ safe_strcpy(g->Message, sizeof(g->Message), "Subtype string too long");
return NULL;
}
else
@@ -118,7 +118,8 @@ PQRYRES OEMColumns(PGLOBAL g, PTOS topt, char* tab, char* db, bool info)
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS, NULL, rc, 0,
(LPTSTR)buf, sizeof(buf), NULL);
- strcat(strcat(g->Message, ": "), buf);
+ safe_strcat(g->Message, sizeof(g->Message), ": ");
+ safe_strcat(g->Message, sizeof(g->Message), buf);
return NULL;
} // endif hDll
@@ -281,7 +282,7 @@ char *RELDEF::GetStringCatInfo(PGLOBAL g, PCSZ what, PCSZ sdef)
if (IsFileType(GetTypeID(ftype))) {
name= Hc->GetPartName();
sval= (char*)PlugSubAlloc(g, NULL, strlen(name) + 12);
- strcat(strcpy(sval, name), ".");
+ snprintf(sval, strlen(name) + 12, "%s.", name);
n= strlen(sval);
// Fold ftype to lower case
@@ -623,12 +624,11 @@ PTABDEF OEMDEF::GetXdef(PGLOBAL g)
/* directories are used (to make this even remotely secure). */
/*********************************************************************/
if (check_valid_path(Module, strlen(Module))) {
- strcpy(g->Message, "Module cannot contain a path");
+ safe_strcpy(g->Message, sizeof(g->Message), "Module cannot contain a path");
return NULL;
} else
// PlugSetPath(soname, Module, GetPluginDir()); // Crashes on Fedora
- strncat(strcpy(soname, GetPluginDir()), Module,
- sizeof(soname) - strlen(soname) - 1);
+ snprintf(soname, sizeof(soname), "%s%s", GetPluginDir(), Module);
#if defined(_WIN32)
// Is the DLL already loaded?
@@ -642,7 +642,8 @@ PTABDEF OEMDEF::GetXdef(PGLOBAL g)
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS, NULL, rc, 0,
(LPTSTR)buf, sizeof(buf), NULL);
- strcat(strcat(g->Message, ": "), buf);
+ safe_strcat(g->Message, sizeof(g->Message), ": ");
+ safe_strcat(g->Message, sizeof(g->Message), buf);
return NULL;
} // endif hDll
@@ -662,7 +663,8 @@ PTABDEF OEMDEF::GetXdef(PGLOBAL g)
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS, NULL, rc, 0,
(LPTSTR)buf, sizeof(buf), NULL);
- strcat(strcat(g->Message, ": "), buf);
+ safe_strcat(g->Message, sizeof(g->Message), ": ");
+ safe_strcat(g->Message, sizeof(g->Message), buf);
FreeLibrary((HMODULE)Hdll);
return NULL;
} // endif getdef
@@ -811,7 +813,7 @@ PTDB OEMDEF::GetTable(PGLOBAL g, MODE mode)
else
txfp = new(g) ZLBFAM(defp);
#else // !GZ_SUPPORT
- strcpy(g->Message, "Compress not supported");
+ safe_strcpy(g->Message, sizeof(g->Message), "Compress not supported");
return NULL;
#endif // !GZ_SUPPORT
} else if (rfm == RECFM_VAR) {
@@ -834,7 +836,7 @@ PTDB OEMDEF::GetTable(PGLOBAL g, MODE mode)
else
txfp = new(g) VCTFAM((PVCTDEF)defp);
#else // !VCT_SUPPORT
- strcpy(g->Message, "VCT no more supported");
+ safe_strcpy(g->Message, sizeof(g->Message), "VCT no more supported");
return NULL;
#endif // !VCT_SUPPORT
} // endif's
@@ -925,7 +927,7 @@ int COLDEF::Define(PGLOBAL g, void *, PCOLINFO cfp, int poff)
return -1;
} // endswitch
- strcpy(F.Type, GetFormatType(Buf_Type));
+ safe_strcpy(F.Type, sizeof(F.Type), GetFormatType(Buf_Type));
F.Length = cfp->Length;
F.Prec = cfp->Scale;
Offset = (cfp->Offset < 0) ? poff : cfp->Offset;
diff --git a/storage/connect/tabbson.cpp b/storage/connect/tabbson.cpp
index 4cbb0e44e19..dfaf2284a72 100644
--- a/storage/connect/tabbson.cpp
+++ b/storage/connect/tabbson.cpp
@@ -39,6 +39,7 @@
#include "checklvl.h"
#include "resource.h"
#include "mycat.h" // for FNC_COL
+#include "m_string.h"
/***********************************************************************/
/* This should be an option. */
@@ -80,7 +81,7 @@ PQRYRES BSONColumns(PGLOBAL g, PCSZ db, PCSZ dsn, PTOS topt, bool info)
} // endif info
if (GetIntegerTableOption(g, topt, "Multiple", 0)) {
- strcpy(g->Message, "Cannot find column definition for multiple table");
+ safe_strcpy(g->Message, sizeof(g->Message), "Cannot find column definition for multiple table");
return NULL;
} // endif Multiple
@@ -206,7 +207,7 @@ int BSONDISC::GetColumns(PGLOBAL g, PCSZ db, PCSZ dsn, PTOS topt)
tdp->Uri = (dsn && *dsn ? dsn : NULL);
if (!tdp->Fn && !tdp->Uri) {
- strcpy(g->Message, MSG(MISSING_FNAME));
+ safe_strcpy(g->Message, sizeof(g->Message), MSG(MISSING_FNAME));
return 0;
} else
topt->subtype = NULL;
@@ -318,7 +319,7 @@ int BSONDISC::GetColumns(PGLOBAL g, PCSZ db, PCSZ dsn, PTOS topt)
switch (tjnp->ReadDB(g)) {
case RC_EF:
- strcpy(g->Message, "Void json table");
+ safe_strcpy(g->Message, sizeof(g->Message), "Void json table");
case RC_FX:
goto err;
default:
@@ -328,7 +329,7 @@ int BSONDISC::GetColumns(PGLOBAL g, PCSZ db, PCSZ dsn, PTOS topt)
} // endif pretty
if (!(row = (jsp) ? bp->GetObject(jsp) : NULL)) {
- strcpy(g->Message, "Can only retrieve columns from object rows");
+ safe_strcpy(g->Message, sizeof(g->Message), "Can only retrieve columns from object rows");
goto err;
} // endif row
@@ -405,7 +406,7 @@ bool BSONDISC::Find(PGLOBAL g, PBVAL jvp, PCSZ key, int j)
if (jvp && !bp->IsJson(jvp)) {
if (JsonAllPath() && !fmt[bf])
- strcat(fmt, colname);
+ safe_strcat(fmt, sizeof(fmt), colname);
jcol.Type = (JTYP)jvp->Type;
@@ -439,7 +440,7 @@ bool BSONDISC::Find(PGLOBAL g, PBVAL jvp, PCSZ key, int j)
jcol.Cbn = true;
} else if (j < lvl && !Stringified(strfy, colname)) {
if (!fmt[bf])
- strcat(fmt, colname);
+ safe_strcat(fmt, sizeof(fmt), colname);
p = fmt + strlen(fmt);
jsp = jvp;
@@ -510,11 +511,11 @@ bool BSONDISC::Find(PGLOBAL g, PBVAL jvp, PCSZ key, int j)
} else if (lvl >= 0) {
if (Stringified(strfy, colname)) {
if (!fmt[bf])
- strcat(fmt, colname);
+ safe_strcat(fmt, sizeof(fmt), colname);
- strcat(fmt, ".*");
+ safe_strcat(fmt, sizeof(fmt), ".*");
} else if (JsonAllPath() && !fmt[bf])
- strcat(fmt, colname);
+ safe_strcat(fmt, sizeof(fmt), colname);
jcol.Type = TYPE_STRG;
jcol.Len = sz;
@@ -961,7 +962,7 @@ PVAL BCUTIL::ExpandArray(PGLOBAL g, PBVAL arp, int n)
} // endif ars
if (!(bvp = GetArrayValue(arp, (nodes[n].Rx = nodes[n].Nx)))) {
- strcpy(g->Message, "Logical error expanding array");
+ safe_strcpy(g->Message, sizeof(g->Message), "Logical error expanding array");
throw 666;
} // endif jvp
@@ -1146,7 +1147,7 @@ PBVAL BCUTIL::GetRow(PGLOBAL g)
} else if (row->Type == TYPE_JAR) {
AddArrayValue(row, (nwr = NewVal(type)));
} else {
- strcpy(g->Message, "Wrong type when writing new row");
+ safe_strcpy(g->Message, sizeof(g->Message), "Wrong type when writing new row");
nwr = NULL;
} // endif's
@@ -1255,7 +1256,7 @@ PTDB BSONDEF::GetTable(PGLOBAL g, MODE m)
// Allocate the parse work memory
G = PlugInit(NULL, (size_t)Lrecl * (Pretty < 0 ? 3 : 5));
} else {
- strcpy(g->Message, "LRECL is not defined");
+ safe_strcpy(g->Message, sizeof(g->Message), "LRECL is not defined");
return NULL;
} // endif Lrecl
@@ -1295,7 +1296,7 @@ PTDB BSONDEF::GetTable(PGLOBAL g, MODE m)
} else if (m == MODE_INSERT) {
txfp = new(g) ZIPFAM(this);
} else {
- strcpy(g->Message, "UPDATE/DELETE not supported for ZIP");
+ safe_strcpy(g->Message, sizeof(g->Message), "UPDATE/DELETE not supported for ZIP");
return NULL;
} // endif's m
#else // !ZIP_SUPPORT
@@ -1325,10 +1326,10 @@ PTDB BSONDEF::GetTable(PGLOBAL g, MODE m)
if (m == MODE_READ || m == MODE_ANY || m == MODE_ALTER) {
txfp = new(g) UNZFAM(this);
} else if (m == MODE_INSERT) {
- strcpy(g->Message, "INSERT supported only for zipped JSON when pretty=0");
+ safe_strcpy(g->Message, sizeof(g->Message), "INSERT supported only for zipped JSON when pretty=0");
return NULL;
} else {
- strcpy(g->Message, "UPDATE/DELETE not supported for ZIP");
+ safe_strcpy(g->Message, sizeof(g->Message), "UPDATE/DELETE not supported for ZIP");
return NULL;
} // endif's m
#else // !ZIP_SUPPORT
@@ -1661,7 +1662,7 @@ bool TDBBSN::PrepareWriting(PGLOBAL g)
strcat(s, ",");
if ((signed)strlen(s) > Lrecl) {
- strncpy(To_Line, s, Lrecl);
+ safe_strcpy(To_Line, Lrecl, s);
snprintf(g->Message, sizeof(g->Message), "Line truncated (lrecl=%d)", Lrecl);
return PushWarning(g, this);
} else
@@ -1764,7 +1765,7 @@ bool BSONCOL::CheckExpand(PGLOBAL g, int i, PSZ nm, bool b)
Xpd = true; // Expandable object
Nodes[i].Op = OP_EXP;
} else if (b) {
- strcpy(g->Message, "Cannot expand more than one branch");
+ safe_strcpy(g->Message, sizeof(g->Message), "Cannot expand more than one branch");
return true;
} // endif Xcol
@@ -1975,7 +1976,7 @@ bool BSONCOL::ParseJpath(PGLOBAL g)
if (SetArrayOptions(g, p, i, Nodes[i - 1].Key))
return true;
else if (Xpd && Tbp->Mode == MODE_DELETE) {
- strcpy(g->Message, "Cannot delete expanded columns");
+ safe_strcpy(g->Message, sizeof(g->Message), "Cannot delete expanded columns");
return true;
} // endif Xpd
@@ -2098,7 +2099,7 @@ void BSONCOL::ReadColumn(PGLOBAL g)
void BSONCOL::WriteColumn(PGLOBAL g)
{
if (Xpd && Tbp->Pretty < 2) {
- strcpy(g->Message, "Cannot write expanded column when Pretty is not 2");
+ safe_strcpy(g->Message, sizeof(g->Message), "Cannot write expanded column when Pretty is not 2");
throw 666;
} // endif Xpd
@@ -2128,7 +2129,7 @@ void BSONCOL::WriteColumn(PGLOBAL g)
char *s = Value->GetCharValue();
if (!(jsp = Cp->ParseJson(g, s, strlen(s)))) {
- strcpy(g->Message, s);
+ safe_strcpy(g->Message, sizeof(g->Message), s);
throw 666;
} // endif jsp
@@ -2314,7 +2315,7 @@ int TDBBSON::MakeDocument(PGLOBAL g)
if (!a && *p && *p != '[' && !IsNum(p)) {
// obj is a key
if (jsp->Type != TYPE_JOB) {
- strcpy(g->Message, "Table path does not match the json file");
+ safe_strcpy(g->Message, sizeof(g->Message), "Table path does not match the json file");
return RC_FX;
} // endif Type
@@ -2340,7 +2341,7 @@ int TDBBSON::MakeDocument(PGLOBAL g)
} // endif p
if (jsp->Type != TYPE_JAR) {
- strcpy(g->Message, "Table path does not match the json file");
+ safe_strcpy(g->Message, sizeof(g->Message), "Table path does not match the json file");
return RC_FX;
} // endif Type
@@ -2434,7 +2435,7 @@ void TDBBSON::ResetSize(void)
int TDBBSON::MakeIndex(PGLOBAL g, PIXDEF pxdf, bool)
{
if (pxdf) {
- strcpy(g->Message, "JSON not indexable when pretty = 2");
+ safe_strcpy(g->Message, sizeof(g->Message), "JSON not indexable when pretty = 2");
return RC_FX;
} else
return RC_OK;
diff --git a/storage/connect/tabdos.cpp b/storage/connect/tabdos.cpp
index 62eecb5e69e..0fdc182f6df 100644
--- a/storage/connect/tabdos.cpp
+++ b/storage/connect/tabdos.cpp
@@ -62,6 +62,7 @@
#include "tabmul.h"
#include "array.h"
#include "blkfil.h"
+#include "m_string.h"
/***********************************************************************/
/* DB static variables. */
@@ -258,7 +259,7 @@ bool DOSDEF::DeleteIndexFile(PGLOBAL g, PIXDEF pxdf)
sep = GetBoolCatInfo("SepIndex", false);
if (!sep && pxdf) {
- strcpy(g->Message, MSG(NO_RECOV_SPACE));
+ safe_strcpy(g->Message, sizeof(g->Message), MSG(NO_RECOV_SPACE));
return true;
} // endif sep
@@ -293,7 +294,8 @@ bool DOSDEF::DeleteIndexFile(PGLOBAL g, PIXDEF pxdf)
for (; pxdf; pxdf = pxdf->GetNext()) {
_splitpath(Ofn, drive, direc, fname, NULL);
- strcat(strcat(fname, "_"), pxdf->GetName());
+ safe_strcat(fname, sizeof(fname), "_");
+ safe_strcat(fname, sizeof(fname), pxdf->GetName());
_makepath(filename, drive, direc, fname, ftype);
PlugSetPath(filename, filename, GetPath());
#if defined(_WIN32)
@@ -312,7 +314,7 @@ bool DOSDEF::DeleteIndexFile(PGLOBAL g, PIXDEF pxdf)
} else { // !sep
// Drop all indexes, delete the common file
PlugSetPath(filename, Ofn, GetPath());
- strcat(PlugRemoveType(filename, filename), ftype);
+ safe_strcat(PlugRemoveType(filename, filename), sizeof(filename), ftype);
#if defined(_WIN32)
if (!DeleteFile(filename))
rc = (GetLastError() != ERROR_FILE_NOT_FOUND);
@@ -365,7 +367,7 @@ PTDB DOSDEF::GetTable(PGLOBAL g, MODE mode)
if (mode == MODE_READ || mode == MODE_ANY || mode == MODE_ALTER) {
txfp = new(g) UZDFAM(this);
} else {
- strcpy(g->Message, "Zipped DBF tables are read only");
+ safe_strcpy(g->Message, sizeof(g->Message), "Zipped DBF tables are read only");
return NULL;
} // endif's mode
@@ -386,7 +388,7 @@ PTDB DOSDEF::GetTable(PGLOBAL g, MODE mode)
} else if (mode == MODE_INSERT) {
txfp = new(g) ZIPFAM(this);
} else {
- strcpy(g->Message, "UPDATE/DELETE not supported for ZIP");
+ safe_strcpy(g->Message, sizeof(g->Message), "UPDATE/DELETE not supported for ZIP");
return NULL;
} // endif's mode
@@ -397,7 +399,7 @@ PTDB DOSDEF::GetTable(PGLOBAL g, MODE mode)
} else if (mode == MODE_INSERT) {
txfp = new(g) ZPXFAM(this);
} else {
- strcpy(g->Message, "UPDATE/DELETE not supported for ZIP");
+ safe_strcpy(g->Message, sizeof(g->Message), "UPDATE/DELETE not supported for ZIP");
return NULL;
} // endif's mode
@@ -655,7 +657,7 @@ int TDBDOS::MakeBlockValues(PGLOBAL g)
if ((nrec = defp->GetElemt()) < 2) {
if (!To_Def->Partitioned()) {
// This may be wrong to do in some cases
- strcpy(g->Message, MSG(TABLE_NOT_OPT));
+ safe_strcpy(g->Message, sizeof(g->Message), MSG(TABLE_NOT_OPT));
return RC_INFO; // Not to be optimized
} else
return RC_OK;
@@ -675,7 +677,7 @@ int TDBDOS::MakeBlockValues(PGLOBAL g)
if ((block = (int)((MaxSize + (int)nrec - 1) / (int)nrec)) < 2) {
// This may be wrong to do in some cases
defp->RemoveOptValues(g);
- strcpy(g->Message, MSG(TABLE_NOT_OPT));
+ safe_strcpy(g->Message, sizeof(g->Message), MSG(TABLE_NOT_OPT));
return RC_INFO; // Not to be optimized
} // endif block
@@ -758,7 +760,7 @@ int TDBDOS::MakeBlockValues(PGLOBAL g)
// No optimised columns. Still useful for blocked variable tables.
if (!colp && defp->Recfm != RECFM_VAR) {
- strcpy(g->Message, "No optimised columns");
+ safe_strcpy(g->Message, sizeof(g->Message), "No optimised columns");
return RC_INFO;
} // endif colp
@@ -788,7 +790,8 @@ int TDBDOS::MakeBlockValues(PGLOBAL g)
/*********************************************************************/
char *p = (char *)PlugSubAlloc(g, NULL, 24 + strlen(Name));
- dup->Step = strcat(strcpy(p, MSG(OPTIMIZING)), Name);
+ snprintf(p, 24 + strlen(Name), "%s%s", MSG(OPTIMIZING), Name);
+ dup->Step = p;
dup->ProgMax = GetProgMax(g);
dup->ProgCur = 0;
#endif // SOCKET_MODE || THREAD
@@ -805,7 +808,7 @@ int TDBDOS::MakeBlockValues(PGLOBAL g)
} else {
if (++curnum >= nrec) {
if (++curblk >= block) {
- strcpy(g->Message, MSG(BAD_BLK_ESTIM));
+ safe_strcpy(g->Message, sizeof(g->Message), MSG(BAD_BLK_ESTIM));
goto err;
} else
curnum = 0;
@@ -833,7 +836,7 @@ int TDBDOS::MakeBlockValues(PGLOBAL g)
#if defined(PROG_INFO)
if (!dup->Step) {
- strcpy(g->Message, MSG(OPT_CANCELLED));
+ safe_strcpy(g->Message, sizeof(g->Message), MSG(OPT_CANCELLED));
goto err;
} else
dup->ProgCur = GetProgCur();
@@ -913,7 +916,8 @@ bool TDBDOS::SaveBlockValues(PGLOBAL g)
if (!(opfile = fopen(filename, "wb"))) {
snprintf(g->Message, sizeof(g->Message), MSG(OPEN_MODE_ERROR),
"wb", (int)errno, filename);
- strcat(strcat(g->Message, ": "), strerror(errno));
+ safe_strcat(g->Message, sizeof(g->Message), ": ");
+ safe_strcat(g->Message, sizeof(g->Message), strerror(errno));
if (trace(1))
htrc("%s\n", g->Message);
@@ -1230,7 +1234,8 @@ bool TDBDOS::GetDistinctColumnValues(PGLOBAL g, int nrec)
/* Initialize progress information */
/*********************************************************************/
p = (char *)PlugSubAlloc(g, NULL, 48 + strlen(Name));
- dup->Step = strcat(strcpy(p, MSG(GET_DIST_VALS)), Name);
+ snprintf(p, 48 + strlen(Name), "%s%s", MSG(GET_DIST_VALS), Name);
+ dup->Step = p;
dup->ProgMax = GetProgMax(g);
dup->ProgCur = 0;
@@ -1242,12 +1247,12 @@ bool TDBDOS::GetDistinctColumnValues(PGLOBAL g, int nrec)
#if defined(SOCKET_MODE)
if (SendProgress(dup)) {
- strcpy(g->Message, MSG(OPT_CANCELLED));
+ safe_strcpy(g->Message, sizeof(g->Message), MSG(OPT_CANCELLED));
return true;
} else
#elif defined(THREAD)
if (!dup->Step) {
- strcpy(g->Message, MSG(OPT_CANCELLED));
+ safe_strcpy(g->Message, sizeof(g->Message), MSG(OPT_CANCELLED));
return true;
} else
#endif // THREAD
@@ -1528,7 +1533,7 @@ PBF TDBDOS::CheckBlockFilari(PGLOBAL g, PXOB *arg, int op, bool *cnv)
} else if (n == 8 || n == 14) {
if (n == 8 && ctype != TYPE_LIST) {
// Should never happen
- strcpy(g->Message, "Block opt: bad constant");
+ safe_strcpy(g->Message, sizeof(g->Message), "Block opt: bad constant");
throw 99;
} // endif Conv
@@ -1686,7 +1691,7 @@ int TDBDOS::MakeIndex(PGLOBAL g, PIXDEF pxdf, bool add)
// Are we are called from CreateTable or CreateIndex?
if (pxdf) {
if (!add && dfp->GetIndx()) {
- strcpy(g->Message, MSG(INDX_EXIST_YET));
+ safe_strcpy(g->Message, sizeof(g->Message), MSG(INDX_EXIST_YET));
return RC_FX;
} // endif To_Indx
@@ -1798,7 +1803,7 @@ int TDBDOS::MakeIndex(PGLOBAL g, PIXDEF pxdf, bool add)
htrc("Exception %d: %s\n", n, g->Message);
rc = RC_FX;
} catch (const char *msg) {
- strcpy(g->Message, msg);
+ safe_strcpy(g->Message, sizeof(g->Message), msg);
rc = RC_FX;
} // end catch
@@ -1832,7 +1837,7 @@ bool TDBDOS::InitialyzeIndex(PGLOBAL g, volatile PIXDEF xdp, bool sorted)
PKPDEF kdp;
if (!xdp && !(xdp = To_Xdp)) {
- strcpy(g->Message, "NULL dynamic index");
+ safe_strcpy(g->Message, sizeof(g->Message), "NULL dynamic index");
return true;
} else
dynamic = To_Filter && xdp->IsUnique() && xdp->IsDynamic();
@@ -1921,7 +1926,7 @@ bool TDBDOS::InitialyzeIndex(PGLOBAL g, volatile PIXDEF xdp, bool sorted)
htrc("Exception %d: %s\n", n, g->Message);
brc = true;
} catch (const char *msg) {
- strcpy(g->Message, msg);
+ safe_strcpy(g->Message, sizeof(g->Message), msg);
brc = true;
} // end catch
@@ -2682,38 +2687,38 @@ void DOSCOL::WriteColumn(PGLOBAL g)
if (Ldz || Nod || Dcm >= 0) {
switch (Buf_Type) {
case TYPE_SHORT:
- strcpy(fmt, (Ldz) ? "%0*hd" : "%*.hd");
+ safe_strcpy(fmt, sizeof(fmt), (Ldz) ? "%0*hd" : "%*.hd");
i = 0;
if (Nod)
for (; i < Dcm; i++)
- strcat(fmt, "0");
+ safe_strcat(fmt, sizeof(fmt), "0");
len = sprintf(Buf, fmt, field - i, Value->GetShortValue());
break;
case TYPE_INT:
- strcpy(fmt, (Ldz) ? "%0*d" : "%*.d");
+ safe_strcpy(fmt, sizeof(fmt), (Ldz) ? "%0*d" : "%*.d");
i = 0;
if (Nod)
for (; i < Dcm; i++)
- strcat(fmt, "0");
+ safe_strcat(fmt,sizeof(fmt), "0");
len = sprintf(Buf, fmt, field - i, Value->GetIntValue());
break;
case TYPE_TINY:
- strcpy(fmt, (Ldz) ? "%0*d" : "%*.d");
+ safe_strcpy(fmt, sizeof(fmt), (Ldz) ? "%0*d" : "%*.d");
i = 0;
if (Nod)
for (; i < Dcm; i++)
- strcat(fmt, "0");
+ safe_strcat(fmt, sizeof(fmt), "0");
len = sprintf(Buf, fmt, field - i, Value->GetTinyValue());
break;
case TYPE_DOUBLE:
case TYPE_DECIM:
- strcpy(fmt, (Ldz) ? "%0*.*lf" : "%*.*lf");
+ safe_strcpy(fmt, sizeof(fmt), (Ldz) ? "%0*.*lf" : "%*.*lf");
len = field + ((Nod && Dcm) ? 1 : 0);
snprintf(Buf, len + 1, fmt, len, Dcm, Value->GetFloatValue());
len = strlen(Buf);
diff --git a/storage/connect/tabext.cpp b/storage/connect/tabext.cpp
index 6ece7115ea5..f558cb04f4d 100644
--- a/storage/connect/tabext.cpp
+++ b/storage/connect/tabext.cpp
@@ -65,7 +65,7 @@ int CONDFIL::Init(PGLOBAL g, PHC hc)
while (alt) {
if (!(p = strchr(alt, '='))) {
- strcpy(g->Message, "Invalid alias list");
+ safe_strcpy(g->Message, sizeof(g->Message), "Invalid alias list");
rc = RC_FX;
break;
} // endif !p
@@ -126,7 +126,7 @@ EXTDEF::EXTDEF(void)
bool EXTDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
{
if (g->Createas) {
- strcpy(g->Message,
+ safe_strcpy(g->Message, sizeof(g->Message),
"Multiple-table UPDATE/DELETE commands are not supported");
return true;
} // endif multi
@@ -349,7 +349,7 @@ bool TDBEXT::MakeSrcdef(PGLOBAL g)
int n_placeholders = count_placeholders(Srcdef);
if (n_placeholders < 0)
{
- strcpy(g->Message, "MakeSQL: Wrong place holders specification");
+ safe_strcpy(g->Message, sizeof(g->Message), "MakeSQL: Wrong place holders specification");
return true;
}
@@ -372,7 +372,7 @@ bool TDBEXT::MakeSrcdef(PGLOBAL g)
Query = new(g)STRING(g, strlen(Srcdef) + strlen(fil1) + strlen(fil2));
Query->SetLength(sprintf(Query->GetStr(), Srcdef, fil2, fil1));
} else {
- strcpy(g->Message, "MakeSQL: Wrong place holders specification");
+ safe_strcpy(g->Message, sizeof(g->Message), "MakeSQL: Wrong place holders specification");
return true;
} // endif's ph
@@ -466,7 +466,7 @@ bool TDBEXT::MakeSQL(PGLOBAL g, bool cnt)
if (Quote) {
// Tabname can have both database and table identifiers, we need to parse
- if ((res= strstr(buf, ".")))
+ if ((res= strstr(buf, ".")))
{
// Parse schema
my_len= res - buf + 1;
@@ -513,7 +513,7 @@ bool TDBEXT::MakeSQL(PGLOBAL g, bool cnt)
len += ((Mode == MODE_READX) ? 256 : 1);
if (Query->IsTruncated()) {
- strcpy(g->Message, "MakeSQL: Out of memory");
+ safe_strcpy(g->Message, sizeof(g->Message), "MakeSQL: Out of memory");
return true;
} else
Query->Resize(len);
@@ -574,6 +574,7 @@ bool TDBEXT::MakeCommand(PGLOBAL g)
bool qtd = Quoted > 0;
char q = qtd ? *Quote : ' ';
int i = 0, k = 0;
+ size_t stmt_sz = 0;
// Make a lower case copy of the originale query and change
// back ticks to the data source identifier quoting character
@@ -585,26 +586,30 @@ bool TDBEXT::MakeCommand(PGLOBAL g)
p[7] = 0; // Remove where clause
Qrystr[(p - qrystr) + 7] = 0;
body = To_CondFil->Body;
- stmt = (char*)PlugSubAlloc(g, NULL, strlen(qrystr)
- + strlen(body) + 64);
+ stmt_sz = strlen(qrystr) + strlen(body) + 64;
} else
- stmt = (char*)PlugSubAlloc(g, NULL, strlen(Qrystr) + 64);
+ stmt_sz = strlen(Qrystr) + 64;
+ stmt = (char*)PlugSubAlloc(g, NULL, stmt_sz);
// Check whether the table name is equal to a keyword
// If so, it must be quoted in the original query
- strlwr(strcat(strcat(strcpy(name, " "), Name), " "));
+ snprintf(name, sizeof(name), " %s ", Name);
+ strlwr(name);
if (strstr(" update delete low_priority ignore quick from ", name)) {
if (Quote) {
- strlwr(strcat(strcat(strcpy(name, Quote), Name), Quote));
+ snprintf(name, sizeof(name), "%s%s%s", Quote, Name, Quote);
+ strlwr(name);
k += 2;
} else {
- strcpy(g->Message, "Quoted must be specified");
+ safe_strcpy(g->Message, sizeof(g->Message), "Quoted must be specified");
return true;
} // endif Quote
- } else
- strlwr(strcpy(name, Name)); // Not a keyword
+ } else {
+ safe_strcpy(name, sizeof(name), Name); // Not a keyword
+ strlwr(name);
+ }
if ((p = strstr(qrystr, name))) {
for (i = 0; i < p - qrystr; i++)
@@ -618,21 +623,29 @@ bool TDBEXT::MakeCommand(PGLOBAL g)
schmp = Schema;
if (qtd && *(p - 1) == ' ') {
- if (schmp)
- strcat(strcat(stmt, schmp), ".");
+ if (schmp) {
+ safe_strcat(stmt, stmt_sz, schmp);
+ safe_strcat(stmt, stmt_sz, ".");
+ }
- strcat(strcat(strcat(stmt, Quote), TableName), Quote);
+ safe_strcat(stmt, stmt_sz, Quote);
+ safe_strcat(stmt, stmt_sz, TableName);
+ safe_strcat(stmt, stmt_sz, Quote);
} else {
if (schmp) {
if (qtd && *(p - 1) != ' ') {
stmt[i - 1] = 0;
- strcat(strcat(strcat(stmt, schmp), "."), Quote);
- } else
- strcat(strcat(stmt, schmp), ".");
+ safe_strcat(stmt, stmt_sz, schmp);
+ safe_strcat(stmt, stmt_sz, ".");
+ safe_strcat(stmt, stmt_sz, Quote);
+ } else {
+ safe_strcat(stmt, stmt_sz, schmp);
+ safe_strcat(stmt, stmt_sz, ".");
+ }
} // endif schmp
- strcat(stmt, TableName);
+ safe_strcat(stmt, stmt_sz, TableName);
} // endif's
i = (int)strlen(stmt);
@@ -644,7 +657,7 @@ bool TDBEXT::MakeCommand(PGLOBAL g)
RemoveConst(g, stmt);
if (body)
- strcat(stmt, body);
+ safe_strcat(stmt, stmt_sz, body);
} else {
snprintf(g->Message, sizeof(g->Message), "Cannot use this %s command",
diff --git a/storage/connect/tabfmt.cpp b/storage/connect/tabfmt.cpp
index 7edffc638fa..037a465af13 100644
--- a/storage/connect/tabfmt.cpp
+++ b/storage/connect/tabfmt.cpp
@@ -62,6 +62,7 @@
#define NO_FUNC
#include "plgcnx.h" // For DB types
#include "resource.h"
+#include "m_string.h"
/***********************************************************************/
/* This should be an option. */
@@ -137,7 +138,7 @@ PQRYRES CSVColumns(PGLOBAL g, PCSZ dp, PTOS topt, bool info)
? strchr(tdp->Entry, '*') || strchr(tdp->Entry, '?')
: GetBooleanTableOption(g, topt, "Mulentries", false);
#else // !ZIP_SUPPORT
- strcpy(g->Message, "ZIP not supported by this version");
+ safe_strcpy(g->Message, sizeof(g->Message), "ZIP not supported by this version");
return NULL;
#endif // !ZIP_SUPPORT
} // endif // Zipped
@@ -145,7 +146,7 @@ PQRYRES CSVColumns(PGLOBAL g, PCSZ dp, PTOS topt, bool info)
fn = tdp->Fn = GetStringTableOption(g, topt, "Filename", NULL);
if (!tdp->Fn) {
- strcpy(g->Message, MSG(MISSING_FNAME));
+ safe_strcpy(g->Message, sizeof(g->Message), MSG(MISSING_FNAME));
return NULL;
} // endif Fn
@@ -472,7 +473,7 @@ bool CSVDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
if (Catfunc == FNC_NO)
for (PCOLDEF cdp = To_Cols; cdp; cdp = cdp->GetNext())
if (cdp->GetOffset() < 1 && !cdp->IsSpecial()) {
- strcpy(g->Message, MSG(BAD_OFFSET_VAL));
+ safe_strcpy(g->Message, sizeof(g->Message), MSG(BAD_OFFSET_VAL));
return true;
} // endif Offset
@@ -528,11 +529,11 @@ PTDB CSVDEF::GetTable(PGLOBAL g, MODE mode)
} else if (mode == MODE_INSERT) {
txfp = new(g) ZIPFAM(this);
} else {
- strcpy(g->Message, "UPDATE/DELETE not supported for ZIP");
+ safe_strcpy(g->Message, sizeof(g->Message), "UPDATE/DELETE not supported for ZIP");
return NULL;
} // endif's mode
#else // !ZIP_SUPPORT
- strcpy(g->Message, "ZIP not supported");
+ safe_strcpy(g->Message, sizeof(g->Message), "ZIP not supported");
return NULL;
#endif // !ZIP_SUPPORT
} else if (map) {
@@ -546,7 +547,7 @@ PTDB CSVDEF::GetTable(PGLOBAL g, MODE mode)
txfp = new(g) ZLBFAM(this);
#else // !GZ_SUPPORT
- strcpy(g->Message, "Compress not supported");
+ safe_strcpy(g->Message, sizeof(g->Message), "Compress not supported");
return NULL;
#endif // !GZ_SUPPORT
} else
@@ -878,7 +879,7 @@ bool TDBCSV::SkipHeader(PGLOBAL g)
if (q)
To_Line[strlen(To_Line)] = Qot;
- strcat(To_Line, cdp->GetName());
+ safe_strcat(To_Line, Lrecl, cdp->GetName());
if (q)
To_Line[strlen(To_Line)] = Qot;
@@ -1048,14 +1049,16 @@ bool TDBCSV::PrepareWriting(PGLOBAL g)
for (i = 0; i < Fields; i++) {
if (i)
- strcat(To_Line, sep);
+ safe_strcat(To_Line, Lrecl, sep);
if (Field[i]) {
if (!strlen(Field[i])) {
// Generally null fields are not quoted
- if (Quoted > 2)
+ if (Quoted > 2) {
// Except if explicitly required
- strcat(strcat(To_Line, qot), qot);
+ safe_strcat(To_Line, Lrecl, qot);
+ safe_strcat(To_Line, Lrecl, qot);
+ }
} else if (Qot && (strchr(Field[i], Sep) || *Field[i] == Qot
|| Quoted > 1 || (Quoted == 1 && !Fldtyp[i]))) {
@@ -1074,12 +1077,15 @@ bool TDBCSV::PrepareWriting(PGLOBAL g)
To_Line[k++] = Qot;
To_Line[k] = '\0';
- } else
- strcat(strcat(strcat(To_Line, qot), Field[i]), qot);
+ } else {
+ safe_strcat(To_Line, Lrecl, qot);
+ safe_strcat(To_Line, Lrecl, Field[i]);
+ safe_strcat(To_Line, Lrecl, qot);
+ }
}
else
- strcat(To_Line, Field[i]);
+ safe_strcat(To_Line, Lrecl, Field[i]);
}
} // endfor i
@@ -1156,7 +1162,7 @@ int TDBCSV::CheckWrite(PGLOBAL g)
} // endif
}
if ((nlen += n) > maxlen) {
- strcpy(g->Message, MSG(LINE_TOO_LONG));
+ safe_strcpy(g->Message, sizeof(g->Message), MSG(LINE_TOO_LONG));
return -1;
} // endif nlen
@@ -1266,7 +1272,7 @@ bool TDBFMT::OpenDB(PGLOBAL g)
} // endif n
FldFormat[i] = (PSZ)PlugSubAlloc(g, NULL, n + 5);
- strcpy(FldFormat[i], pfm);
+ safe_strcpy(FldFormat[i], n + 5, pfm);
if (!strcmp(pfm + n, "%m")) {
// This is a field that can be missing. Flag it so it can
@@ -1276,7 +1282,7 @@ bool TDBFMT::OpenDB(PGLOBAL g)
} else if (i+1 < Fields && strcmp(pfm + n, "%n")) {
// There are trailing characters after the field contents
// add a marker for the next field start position.
- strcat(FldFormat[i], "%n");
+ safe_strcat(FldFormat[i], n + 5, "%n");
FmtTest[i] = 1;
} // endif's
diff --git a/storage/connect/tabjdbc.cpp b/storage/connect/tabjdbc.cpp
index 46fb7695a51..0242832b02f 100644
--- a/storage/connect/tabjdbc.cpp
+++ b/storage/connect/tabjdbc.cpp
@@ -277,7 +277,7 @@ PTDB JDBCDEF::GetTable(PGLOBAL g, MODE m)
if (Multiple == 1)
tdbp = new(g)TDBMUL(tdbp);
else if (Multiple == 2)
- strcpy(g->Message, "NO_JDBC_MUL");
+ safe_strcpy(g->Message, sizeof(g->Message), "NO_JDBC_MUL");
} // endswitch Catfunc
@@ -386,7 +386,7 @@ bool TDBJDBC::MakeInsert(PGLOBAL g)
for (colp = Columns; colp; colp = colp->GetNext())
if (colp->IsSpecial()) {
- strcpy(g->Message, "No JDBC special columns");
+ safe_strcpy(g->Message, sizeof(g->Message), "No JDBC special columns");
return true;
} else {
// Column name can be encoded in UTF-8
@@ -460,7 +460,7 @@ bool TDBJDBC::MakeInsert(PGLOBAL g)
} // endfor colp
if ((Query->Append(") VALUES ("))) {
- strcpy(g->Message, "MakeInsert: Out of memory");
+ safe_strcpy(g->Message, sizeof(g->Message), "MakeInsert: Out of memory");
return true;
} else // in case prepared statement fails
pos = Query->GetLength();
@@ -470,7 +470,7 @@ bool TDBJDBC::MakeInsert(PGLOBAL g)
Query->Append("?,");
if (Query->IsTruncated()) {
- strcpy(g->Message, "MakeInsert: Out of memory");
+ safe_strcpy(g->Message, sizeof(g->Message), "MakeInsert: Out of memory");
return true;
} else
Query->RepLast(')');
@@ -532,12 +532,15 @@ int TDBJDBC::Cardinality(PGLOBAL g)
// Table name can be encoded in UTF-8
Decode(TableName, tbn, sizeof(tbn));
- strcpy(qry, "SELECT COUNT(*) FROM ");
+ safe_strcpy(qry, sizeof(qry), "SELECT COUNT(*) FROM ");
- if (Quote)
- strcat(strcat(strcat(qry, Quote), tbn), Quote);
+ if (Quote) {
+ safe_strcat(qry, sizeof(qry), Quote);
+ safe_strcat(qry, sizeof(qry), tbn);
+ safe_strcat(qry, sizeof(qry), Quote);
+ }
else
- strcat(qry, tbn);
+ safe_strcat(qry, sizeof(qry), tbn);
// Allocate a Count(*) column (must not use the default constructor)
Cnp = new(g)JDBCCOL;
@@ -656,7 +659,7 @@ bool TDBJDBC::OpenDB(PGLOBAL g)
if ((Qrp = Jcp->AllocateResult(g, this)))
Memory = 2; // Must be filled
else {
- strcpy(g->Message, "Result set memory allocation failed");
+ safe_strcpy(g->Message, sizeof(g->Message), "Result set memory allocation failed");
return true;
} // endif n
@@ -683,7 +686,7 @@ bool TDBJDBC::OpenDB(PGLOBAL g)
#if 0
if (!(rc = MakeInsert(g))) {
if (Nparm != Jcp->PrepareSQL(Query->GetStr())) {
- strcpy(g->Message, MSG(PARM_CNT_MISS));
+ safe_strcpy(g->Message, sizeof(g->Message), MSG(PARM_CNT_MISS));
rc = true;
} else
rc = BindParameters(g);
@@ -735,12 +738,12 @@ bool TDBJDBC::SetRecpos(PGLOBAL g, int recpos)
CurNum = recpos;
Fpos = recpos;
} else {
- strcpy(g->Message, "Scrolling out of row set NIY");
+ safe_strcpy(g->Message, sizeof(g->Message), "Scrolling out of row set NIY");
return true;
} // endif recpos
} else {
- strcpy(g->Message, "This action requires a scrollable cursor");
+ safe_strcpy(g->Message, sizeof(g->Message), "This action requires a scrollable cursor");
return true;
} // endif's
@@ -786,7 +789,7 @@ bool TDBJDBC::ReadKey(PGLOBAL g, OPVAL op, const key_range *kr)
if (To_CondFil)
if (Query->Append(" AND ") || Query->Append(To_CondFil->Body)) {
- strcpy(g->Message, "Readkey: Out of memory");
+ safe_strcpy(g->Message, sizeof(g->Message), "Readkey: Out of memory");
return true;
} // endif Append
@@ -919,7 +922,7 @@ int TDBJDBC::WriteDB(PGLOBAL g)
} // endfor colp
if (unlikely(Query->IsTruncated())) {
- strcpy(g->Message, "WriteDB: Out of memory");
+ safe_strcpy(g->Message, sizeof(g->Message), "WriteDB: Out of memory");
return RC_FX;
} // endif Query
@@ -1112,13 +1115,13 @@ PCMD TDBXJDC::MakeCMD(PGLOBAL g)
(To_CondFil->Op == OP_EQ || To_CondFil->Op == OP_IN)) {
xcmd = To_CondFil->Cmds;
} else
- strcpy(g->Message, "Invalid command specification filter");
+ safe_strcpy(g->Message, sizeof(g->Message), "Invalid command specification filter");
} else
- strcpy(g->Message, "No command column in select list");
+ safe_strcpy(g->Message, sizeof(g->Message), "No command column in select list");
} else if (!Srcdef)
- strcpy(g->Message, "No Srcdef default command");
+ safe_strcpy(g->Message, sizeof(g->Message), "No Srcdef default command");
else
xcmd = new(g) CMD(g, Srcdef);
@@ -1149,7 +1152,7 @@ bool TDBXJDC::OpenDB(PGLOBAL g)
this, Tdb_No, Use, Mode);
if (Use == USE_OPEN) {
- strcpy(g->Message, "Multiple execution is not allowed");
+ safe_strcpy(g->Message, sizeof(g->Message), "Multiple execution is not allowed");
return true;
} // endif use
@@ -1171,7 +1174,7 @@ bool TDBXJDC::OpenDB(PGLOBAL g)
Use = USE_OPEN; // Do it now in case we are recursively called
if (Mode != MODE_READ && Mode != MODE_READX) {
- strcpy(g->Message, "No INSERT/DELETE/UPDATE of XJDBC tables");
+ safe_strcpy(g->Message, sizeof(g->Message), "No INSERT/DELETE/UPDATE of XJDBC tables");
return true;
} // endif Mode
@@ -1224,7 +1227,7 @@ int TDBXJDC::ReadDB(PGLOBAL g)
/***********************************************************************/
int TDBXJDC::WriteDB(PGLOBAL g)
{
- strcpy(g->Message, "Execsrc tables are read only");
+ safe_strcpy(g->Message, sizeof(g->Message), "Execsrc tables are read only");
return RC_FX;
} // end of DeleteDB
@@ -1233,7 +1236,7 @@ int TDBXJDC::WriteDB(PGLOBAL g)
/***********************************************************************/
int TDBXJDC::DeleteDB(PGLOBAL g, int irc)
{
- strcpy(g->Message, "NO_XJDBC_DELETE");
+ safe_strcpy(g->Message, sizeof(g->Message), "NO_XJDBC_DELETE");
return RC_FX;
} // end of DeleteDB
diff --git a/storage/connect/tabjson.cpp b/storage/connect/tabjson.cpp
index 968253ec8d1..27bdfee5f35 100644
--- a/storage/connect/tabjson.cpp
+++ b/storage/connect/tabjson.cpp
@@ -85,7 +85,7 @@ PQRYRES JSONColumns(PGLOBAL g, PCSZ db, PCSZ dsn, PTOS topt, bool info)
} // endif info
if (GetIntegerTableOption(g, topt, "Multiple", 0)) {
- strcpy(g->Message, "Cannot find column definition for multiple table");
+ safe_strcpy(g->Message, sizeof(g->Message), "Cannot find column definition for multiple table");
return NULL;
} // endif Multiple
@@ -212,7 +212,7 @@ int JSONDISC::GetColumns(PGLOBAL g, PCSZ db, PCSZ dsn, PTOS topt)
tdp->Uri = (dsn && *dsn ? dsn : NULL);
if (!tdp->Fn && !tdp->Uri) {
- strcpy(g->Message, MSG(MISSING_FNAME));
+ safe_strcpy(g->Message, sizeof(g->Message), MSG(MISSING_FNAME));
return 0;
} else
topt->subtype = NULL;
@@ -320,7 +320,7 @@ int JSONDISC::GetColumns(PGLOBAL g, PCSZ db, PCSZ dsn, PTOS topt)
switch (tjnp->ReadDB(g)) {
case RC_EF:
- strcpy(g->Message, "Void json table");
+ safe_strcpy(g->Message, sizeof(g->Message), "Void json table");
case RC_FX:
goto err;
default:
@@ -333,7 +333,7 @@ int JSONDISC::GetColumns(PGLOBAL g, PCSZ db, PCSZ dsn, PTOS topt)
} // endif pretty
if (!(row = (jsp) ? jsp->GetObject() : NULL)) {
- strcpy(g->Message, "Can only retrieve columns from object rows");
+ safe_strcpy(g->Message, sizeof(g->Message), "Can only retrieve columns from object rows");
goto err;
} // endif row
@@ -417,7 +417,7 @@ bool JSONDISC::Find(PGLOBAL g, PJVAL jvp, PCSZ key, int j)
if (jvp && jvp->DataType != TYPE_JSON) {
if (JsonAllPath() && !fmt[bf])
- strcat(fmt, colname);
+ safe_strcat(fmt, sizeof(fmt), colname);
jcol.Type = jvp->DataType;
@@ -450,7 +450,7 @@ bool JSONDISC::Find(PGLOBAL g, PJVAL jvp, PCSZ key, int j)
jcol.Cbn = true;
} else if (j < lvl && !Stringified(strfy, colname)) {
if (!fmt[bf])
- strcat(fmt, colname);
+ safe_strcat(fmt, sizeof(fmt), colname);
p = fmt + strlen(fmt);
jsp = jvp->GetJson();
@@ -520,11 +520,11 @@ bool JSONDISC::Find(PGLOBAL g, PJVAL jvp, PCSZ key, int j)
} else if (lvl >= 0) {
if (Stringified(strfy, colname)) {
if (!fmt[bf])
- strcat(fmt, colname);
+ safe_strcat(fmt, sizeof(fmt), colname);
- strcat(fmt, ".*");
+ safe_strcat(fmt, sizeof(fmt), ".*");
} else if (JsonAllPath() && !fmt[bf])
- strcat(fmt, colname);
+ safe_strcat(fmt, sizeof(fmt), colname);
jcol.Type = TYPE_STRG;
jcol.Len = sz;
@@ -735,7 +735,7 @@ PTDB JSONDEF::GetTable(PGLOBAL g, MODE m)
} else if (m == MODE_INSERT) {
txfp = new(g) ZIPFAM(this);
} else {
- strcpy(g->Message, "UPDATE/DELETE not supported for ZIP");
+ safe_strcpy(g->Message, sizeof(g->Message), "UPDATE/DELETE not supported for ZIP");
return NULL;
} // endif's m
#else // !ZIP_SUPPORT
@@ -775,7 +775,7 @@ PTDB JSONDEF::GetTable(PGLOBAL g, MODE m)
#endif // 0
((TDBJSN*)tdbp)->G = PlugInit(NULL, (size_t)Lrecl * (Pretty >= 0 ? 12 : 4));
} else {
- strcpy(g->Message, "LRECL is not defined");
+ safe_strcpy(g->Message, sizeof(g->Message), "LRECL is not defined");
return NULL;
} // endif Lrecl
@@ -785,10 +785,10 @@ PTDB JSONDEF::GetTable(PGLOBAL g, MODE m)
if (m == MODE_READ || m == MODE_ANY || m == MODE_ALTER) {
txfp = new(g) UNZFAM(this);
} else if (m == MODE_INSERT) {
- strcpy(g->Message, "INSERT supported only for zipped JSON when pretty=0");
+ safe_strcpy(g->Message, sizeof(g->Message), "INSERT supported only for zipped JSON when pretty=0");
return NULL;
} else {
- strcpy(g->Message, "UPDATE/DELETE not supported for ZIP");
+ safe_strcpy(g->Message, sizeof(g->Message), "UPDATE/DELETE not supported for ZIP");
return NULL;
} // endif's m
#else // !ZIP_SUPPORT
@@ -1144,7 +1144,7 @@ int TDBJSN::ReadDB(PGLOBAL g) {
M = 1;
rc = RC_OK;
} else if (Pretty != 1 || strcmp(To_Line, "]")) {
- strcpy(g->Message, G->Message);
+ safe_strcpy(g->Message, sizeof(g->Message), G->Message);
rc = RC_FX;
} else
rc = RC_EF;
@@ -1257,7 +1257,7 @@ bool TDBJSN::PrepareWriting(PGLOBAL g)
strcat(s, ",");
if ((signed)strlen(s) > Lrecl) {
- strncpy(To_Line, s, Lrecl);
+ safe_strcpy(To_Line, Lrecl, s);
snprintf(g->Message, sizeof(g->Message), "Line truncated (lrecl=%d)", Lrecl);
return PushWarning(g, this);
} else
@@ -1359,7 +1359,7 @@ bool JSONCOL::CheckExpand(PGLOBAL g, int i, PSZ nm, bool b)
Xpd = true; // Expandable object
Nodes[i].Op = OP_EXP;
} else if (b) {
- strcpy(g->Message, "Cannot expand more than one branch");
+ safe_strcpy(g->Message, sizeof(g->Message), "Cannot expand more than one branch");
return true;
} // endif Xcol
@@ -1570,7 +1570,7 @@ bool JSONCOL::ParseJpath(PGLOBAL g)
if (SetArrayOptions(g, p, i, Nodes[i - 1].Key))
return true;
else if (Xpd && Tjp->Mode == MODE_DELETE) {
- strcpy(g->Message, "Cannot delete expanded columns");
+ safe_strcpy(g->Message, sizeof(g->Message), "Cannot delete expanded columns");
return true;
} // endif Xpd
@@ -1674,7 +1674,7 @@ PSZ JSONCOL::GetJpath(PGLOBAL g, bool proj)
PVAL JSONCOL::MakeJson(PGLOBAL g, PJSON jsp, int n)
{
if (Value->IsTypeNum()) {
- strcpy(g->Message, "Cannot make Json for a numeric column");
+ safe_strcpy(g->Message, sizeof(g->Message), "Cannot make Json for a numeric column");
if (!Warned) {
PushWarning(g, Tjp);
@@ -1689,10 +1689,10 @@ PVAL JSONCOL::MakeJson(PGLOBAL g, PJSON jsp, int n)
ulong len = Tjp->Lrecl ? Tjp->Lrecl : 500;
PBSON bsp = JbinAlloc(g, NULL, len, jsp);
- strcat(bsp->Msg, " column");
+ safe_strcat(bsp->Msg, sizeof(bsp->Msg), " column");
((BINVAL*)Value)->SetBinValue(bsp, sizeof(BSON));
} else {
- strcpy(g->Message, "Column size too small");
+ safe_strcpy(g->Message, sizeof(g->Message), "Column size too small");
Value->SetValue_char(NULL, 0);
} // endif Clen
#endif // 0
@@ -1934,7 +1934,7 @@ PVAL JSONCOL::ExpandArray(PGLOBAL g, PJAR arp, int n)
} // endif ars
if (!(jvp = arp->GetArrayValue((Nodes[n].Rx = Nodes[n].Nx)))) {
- strcpy(g->Message, "Logical error expanding array");
+ safe_strcpy(g->Message, sizeof(g->Message), "Logical error expanding array");
throw 666;
} // endif jvp
@@ -2122,7 +2122,7 @@ PJSON JSONCOL::GetRow(PGLOBAL g)
((PJAR)row)->AddArrayValue(G, new(G) JVALUE(nwr));
((PJAR)row)->InitArray(G);
} else {
- strcpy(g->Message, "Wrong type when writing new row");
+ safe_strcpy(g->Message, sizeof(g->Message), "Wrong type when writing new row");
nwr = NULL;
} // endif's
@@ -2143,7 +2143,7 @@ PJSON JSONCOL::GetRow(PGLOBAL g)
void JSONCOL::WriteColumn(PGLOBAL g)
{
if (Xpd && Tjp->Pretty < 2) {
- strcpy(g->Message, "Cannot write expanded column when Pretty is not 2");
+ safe_strcpy(g->Message, sizeof(g->Message), "Cannot write expanded column when Pretty is not 2");
throw 666;
} // endif Xpd
@@ -2179,7 +2179,7 @@ void JSONCOL::WriteColumn(PGLOBAL g)
if (s && *s) {
if (!(jsp = ParseJson(G, s, strlen(s)))) {
- strcpy(g->Message, s);
+ safe_strcpy(g->Message, sizeof(g->Message), s);
throw 666;
} // endif jsp
@@ -2362,7 +2362,7 @@ int TDBJSON::MakeDocument(PGLOBAL g)
if (!a && *p && *p != '[' && !IsNum(p)) {
// obj is a key
if (jsp->GetType() != TYPE_JOB) {
- strcpy(g->Message, "Table path does not match the json file");
+ safe_strcpy(g->Message, sizeof(g->Message), "Table path does not match the json file");
return RC_FX;
} // endif Type
@@ -2388,7 +2388,7 @@ int TDBJSON::MakeDocument(PGLOBAL g)
} // endif p
if (jsp->GetType() != TYPE_JAR) {
- strcpy(g->Message, "Table path does not match the json file");
+ safe_strcpy(g->Message, sizeof(g->Message), "Table path does not match the json file");
return RC_FX;
} // endif Type
@@ -2483,7 +2483,7 @@ void TDBJSON::ResetSize(void)
int TDBJSON::MakeIndex(PGLOBAL g, PIXDEF pxdf, bool)
{
if (pxdf) {
- strcpy(g->Message, "JSON not indexable when pretty = 2");
+ safe_strcpy(g->Message, sizeof(g->Message), "JSON not indexable when pretty = 2");
return RC_FX;
} else
return RC_OK;
diff --git a/storage/connect/value.cpp b/storage/connect/value.cpp
index 498ec71a87f..7265b2ed0ca 100644
--- a/storage/connect/value.cpp
+++ b/storage/connect/value.cpp
@@ -163,9 +163,9 @@ PCSZ GetTypeName(int type)
/***********************************************************************/
/* GetTypeSize: returns the PlugDB internal type size. */
/***********************************************************************/
-int GetTypeSize(int type, int len)
- {
- switch (type) {
+unsigned GetTypeSize(int type, unsigned len)
+{
+ switch (type) {
case TYPE_DECIM:
case TYPE_BIN:
case TYPE_STRING: len = len * sizeof(char); break;
@@ -176,7 +176,7 @@ int GetTypeSize(int type, int len)
case TYPE_DOUBLE: len = sizeof(double); break;
case TYPE_TINY: len = sizeof(char); break;
case TYPE_PCHAR: len = sizeof(char*); break;
- default: len = -1;
+ default: len = 0;
} // endswitch type
return len;
diff --git a/storage/connect/value.h b/storage/connect/value.h
index a0d947347c3..7eb0dec29f2 100644
--- a/storage/connect/value.h
+++ b/storage/connect/value.h
@@ -41,7 +41,7 @@ typedef struct _datpar *PDTP; // For DTVAL
/***********************************************************************/
// Exported functions
DllExport PCSZ GetTypeName(int);
-DllExport int GetTypeSize(int, int);
+DllExport unsigned GetTypeSize(int, unsigned);
#ifdef ODBC_SUPPORT
/* This function is exported for use in OEM table type DLLs */
DllExport int TranslateSQLType(int stp, int prec,