diff options
Diffstat (limited to 'storage/connect')
-rw-r--r-- | storage/connect/catalog.h | 4 | ||||
-rw-r--r-- | storage/connect/mysql-test/connect/r/mysql.result | 11 | ||||
-rw-r--r-- | storage/connect/mysql-test/connect/t/mysql.test | 15 | ||||
-rw-r--r-- | storage/connect/myutil.cpp | 2 | ||||
-rw-r--r-- | storage/connect/reldef.cpp | 26 | ||||
-rw-r--r-- | storage/connect/tabbson.cpp | 47 | ||||
-rw-r--r-- | storage/connect/tabdos.cpp | 61 | ||||
-rw-r--r-- | storage/connect/tabext.cpp | 57 | ||||
-rw-r--r-- | storage/connect/tabfmt.cpp | 38 | ||||
-rw-r--r-- | storage/connect/tabjdbc.cpp | 45 | ||||
-rw-r--r-- | storage/connect/tabjson.cpp | 54 | ||||
-rw-r--r-- | storage/connect/value.cpp | 8 | ||||
-rw-r--r-- | storage/connect/value.h | 2 |
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, |