summaryrefslogtreecommitdiff
path: root/storage
diff options
context:
space:
mode:
authorMikhail Chalov <mcchalov@amazon.com>2022-11-15 14:39:30 -0800
committerVicențiu Ciorbaru <cvicentiu@gmail.com>2023-01-20 15:18:52 +0200
commit567b68129943a1cceab1d7b4c68e2a4ba011cdc0 (patch)
tree310e63987deb21ca563cfb86a2cf461f5b9ca133 /storage
parentea270178b09bb1e2e1131957e95f36cd1f611b22 (diff)
downloadmariadb-git-567b68129943a1cceab1d7b4c68e2a4ba011cdc0.tar.gz
Minimize unsafe C functions usage - replace strcat() and strcpy() (and strncat() and strncpy()) with custom safe_strcat() and safe_strcpy() functions
The MariaDB code base uses strcat() and strcpy() in several places. These are known to have memory safety issues and their usage is discouraged. Common security scanners like Flawfinder flags them. In MariaDB we should start using modern and safer variants on these functions. This is similar to memory issues fixes in 19af1890b56c6c147c296479bb6a4ad00fa59dbb and 9de9f105b5cb88249acc39af73d32af337d6fd5f but now replace use of strcat() and strcpy() with safer options strncat() and strncpy(). However, add '\0' forcefully to make sure the result string is correct since for these two functions it is not guaranteed what new string will be null-terminated. Example: size_t dest_len = sizeof(g->Message); strncpy(g->Message, "Null json tree", dest_len); strncat(g->Message, ":", sizeof(g->Message) - strlen(g->Message)); size_t wrote_sz = strlen(g->Message); size_t cur_len = wrote_sz >= dest_len ? dest_len - 1 : wrote_sz; g->Message[cur_len] = '\0'; All new code of the whole pull request, including one or several files that are either new files or modified ones, are contributed under the BSD-new license. I am contributing on behalf of my employer Amazon Web Services -- Reviewer and co-author Vicențiu Ciorbaru <vicentiu@mariadb.org> -- Reviewer additions: * The initial function implementation was flawed. Replaced with a simpler and also correct version. * Simplified code by making use of snprintf instead of chaining strcat. * Simplified code by removing dynamic string construction in the first place and using static strings if possible. See connect storage engine changes.
Diffstat (limited to 'storage')
-rw-r--r--storage/connect/array.cpp6
-rw-r--r--storage/connect/bson.cpp8
-rw-r--r--storage/connect/bsonudf.cpp20
-rw-r--r--storage/connect/filamdbf.cpp2
-rw-r--r--storage/connect/filamfix.cpp17
-rw-r--r--storage/connect/filamgz.cpp19
-rw-r--r--storage/connect/filamtxt.cpp10
-rw-r--r--storage/connect/filamvct.cpp39
-rw-r--r--storage/connect/filamzip.cpp10
-rw-r--r--storage/connect/javaconn.cpp27
-rw-r--r--storage/connect/json.cpp8
-rw-r--r--storage/connect/jsonudf.cpp21
-rw-r--r--storage/connect/myconn.cpp12
13 files changed, 109 insertions, 90 deletions
diff --git a/storage/connect/array.cpp b/storage/connect/array.cpp
index a5c2e065742..1eeb4ac05ca 100644
--- a/storage/connect/array.cpp
+++ b/storage/connect/array.cpp
@@ -975,13 +975,13 @@ PSZ ARRAY::MakeArrayList(PGLOBAL g)
xtrc(1, "Arraylist: len=%d\n", len);
p = (char *)PlugSubAlloc(g, NULL, len);
- strcpy(p, "(");
+ safe_strcpy(p, len, "(");
for (i = 0; i < Nval;) {
Value->SetValue_pvblk(Vblp, i);
Value->Prints(g, tp, z);
- strcat(p, tp);
- strcat(p, (++i == Nval) ? ")" : ",");
+ safe_strcat(p, len, tp);
+ safe_strcat(p, len, (++i == Nval) ? ")" : ",");
} // enfor i
xtrc(1, "Arraylist: newlen=%d\n", strlen(p));
diff --git a/storage/connect/bson.cpp b/storage/connect/bson.cpp
index 1a1c5cf5d8d..208cd04cb3a 100644
--- a/storage/connect/bson.cpp
+++ b/storage/connect/bson.cpp
@@ -10,6 +10,7 @@
/* Include relevant sections of the MariaDB header file. */
/***********************************************************************/
#include <my_global.h>
+#include <m_string.h>
/***********************************************************************/
/* Include application header files: */
@@ -598,7 +599,7 @@ PSZ BDOC::Serialize(PGLOBAL g, PBVAL bvp, char* fn, int pretty)
try {
if (!bvp) {
- strcpy(g->Message, "Null json tree");
+ safe_strcpy(g->Message, sizeof(g->Message), "Null json tree");
throw 1;
} else if (!fn) {
// Serialize to a string
@@ -606,9 +607,8 @@ PSZ BDOC::Serialize(PGLOBAL g, PBVAL bvp, char* fn, int pretty)
b = pretty == 1;
} else {
if (!(fs = fopen(fn, "wb"))) {
- snprintf(g->Message, sizeof(g->Message), MSG(OPEN_MODE_ERROR),
- "w", (int)errno, fn);
- strcat(strcat(g->Message, ": "), strerror(errno));
+ snprintf(g->Message, sizeof(g->Message), MSG(OPEN_MODE_ERROR) ": %s",
+ "w", (int)errno, fn, strerror(errno));
throw 2;
} else if (pretty >= 2) {
// Serialize to a pretty file
diff --git a/storage/connect/bsonudf.cpp b/storage/connect/bsonudf.cpp
index 2d9132e20ed..8df04232277 100644
--- a/storage/connect/bsonudf.cpp
+++ b/storage/connect/bsonudf.cpp
@@ -4908,7 +4908,7 @@ char *bbin_make_array(UDF_INIT *initid, UDF_ARGS *args, char *result,
} // endfor i
if ((bsp = BbinAlloc(bnx.G, initid->max_length, arp))) {
- strcat(bsp->Msg, " array");
+ safe_strcat(bsp->Msg, sizeof(bsp->Msg), " array");
// Keep result of constant function
g->Xchk = (initid->const_item) ? bsp : NULL;
@@ -5106,8 +5106,9 @@ char *bbin_array_grp(UDF_INIT *initid, UDF_ARGS *, char *result,
PUSH_WARNING("Result truncated to json_grp_size values");
if (arp)
- if ((bsp = BbinAlloc(g, initid->max_length, arp)))
- strcat(bsp->Msg, " array");
+ if ((bsp = BbinAlloc(g, initid->max_length, arp))) {
+ safe_strcat(bsp->Msg, sizeof(bsp->Msg), " array");
+ }
if (!bsp) {
*res_length = 0;
@@ -5153,8 +5154,9 @@ char *bbin_object_grp(UDF_INIT *initid, UDF_ARGS *, char *result,
PUSH_WARNING("Result truncated to json_grp_size values");
if (bop)
- if ((bsp = BbinAlloc(g, initid->max_length, bop)))
- strcat(bsp->Msg, " object");
+ if ((bsp = BbinAlloc(g, initid->max_length, bop))) {
+ safe_strcat(bsp->Msg, sizeof(bsp->Msg), " object");
+ }
if (!bsp) {
*res_length = 0;
@@ -5198,7 +5200,7 @@ char *bbin_make_object(UDF_INIT *initid, UDF_ARGS *args, char *result,
bnx.SetKeyValue(objp, bnx.MakeValue(args, i), bnx.MakeKey(args, i));
if ((bsp = BbinAlloc(bnx.G, initid->max_length, objp))) {
- strcat(bsp->Msg, " object");
+ safe_strcat(bsp->Msg, sizeof(bsp->Msg), " object");
// Keep result of constant function
g->Xchk = (initid->const_item) ? bsp : NULL;
@@ -5253,7 +5255,7 @@ char *bbin_object_nonull(UDF_INIT *initid, UDF_ARGS *args, char *result,
bnx.SetKeyValue(objp, jvp, bnx.MakeKey(args, i));
if ((bsp = BbinAlloc(bnx.G, initid->max_length, objp))) {
- strcat(bsp->Msg, " object");
+ safe_strcat(bsp->Msg, sizeof(bsp->Msg), " object");
// Keep result of constant function
g->Xchk = (initid->const_item) ? bsp : NULL;
@@ -5312,7 +5314,7 @@ char *bbin_object_key(UDF_INIT *initid, UDF_ARGS *args, char *result,
bnx.SetKeyValue(objp, bnx.MakeValue(args, i + 1), MakePSZ(g, args, i));
if ((bsp = BbinAlloc(bnx.G, initid->max_length, objp))) {
- strcat(bsp->Msg, " object");
+ safe_strcat(bsp->Msg, sizeof(bsp->Msg), " object");
// Keep result of constant function
g->Xchk = (initid->const_item) ? bsp : NULL;
@@ -6075,7 +6077,7 @@ char *bbin_file(UDF_INIT *initid, UDF_ARGS *args, char *result,
// pretty = pty;
if ((bsp = BbinAlloc(bnx.G, len, jsp))) {
- strcat(bsp->Msg, " file");
+ safe_strcat(bsp->Msg, sizeof(bsp->Msg), " file");
bsp->Filename = fn;
bsp->Pretty = pretty;
} else {
diff --git a/storage/connect/filamdbf.cpp b/storage/connect/filamdbf.cpp
index a4c2232b1bf..c5694c06b65 100644
--- a/storage/connect/filamdbf.cpp
+++ b/storage/connect/filamdbf.cpp
@@ -442,7 +442,7 @@ PQRYRES DBFColumns(PGLOBAL g, PCSZ dp, PCSZ fn, PTOS topt, bool info)
hp->Headlen, hp->Filedate[0], hp->Filedate[1],
hp->Filedate[2]);
- strcat(g->Message, buf);
+ safe_strcat(g->Message, sizeof(g->Message), buf);
} // endif info
#endif // 0
diff --git a/storage/connect/filamfix.cpp b/storage/connect/filamfix.cpp
index 1df247bd951..d767ba6e4bc 100644
--- a/storage/connect/filamfix.cpp
+++ b/storage/connect/filamfix.cpp
@@ -36,6 +36,8 @@
#include <fcntl.h>
#endif // !_WIN32
+#include <m_string.h>
+
/***********************************************************************/
/* Include application header files: */
/* global.h is header containing all global declarations. */
@@ -883,7 +885,6 @@ bool BGXFAM::OpenTableFile(PGLOBAL g)
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS, NULL, rc, 0,
(LPTSTR)filename, sizeof(filename), NULL);
- strcat(g->Message, filename);
} else
rc = 0;
@@ -1004,7 +1005,7 @@ int BGXFAM::Cardinality(PGLOBAL g)
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS, NULL, rc, 0,
(LPTSTR)filename, sizeof(filename), NULL);
- strcat(g->Message, filename);
+ safe_strcat(g->Message, sizeof(g->Message), filename);
return -1;
} else
return 0; // File does not exist
@@ -1384,7 +1385,8 @@ bool BGXFAM::OpenTempFile(PGLOBAL g)
/*********************************************************************/
tempname = (char*)PlugSubAlloc(g, NULL, _MAX_PATH);
PlugSetPath(tempname, To_File, Tdbp->GetPath());
- strcat(PlugRemoveType(tempname, tempname), ".t");
+ PlugRemoveType(tempname, tempname);
+ safe_strcat(tempname, _MAX_PATH, ".t");
remove(tempname); // Be sure it does not exist yet
#if defined(_WIN32)
@@ -1393,11 +1395,12 @@ bool BGXFAM::OpenTempFile(PGLOBAL g)
if (Tfile == INVALID_HANDLE_VALUE) {
DWORD rc = GetLastError();
- snprintf(g->Message, sizeof(g->Message), MSG(OPEN_ERROR), rc, MODE_INSERT, tempname);
+ snprintf(g->Message, sizeof(g->Message), MSG(OPEN_ERROR), rc, MODE_INSERT,
+ tempname);
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS, NULL, rc, 0,
(LPTSTR)tempname, _MAX_PATH, NULL);
- strcat(g->Message, tempname);
+ safe_strcat(g->Message, sizeof(g->Message), tempname);
return true;
} // endif Tfile
#else // UNIX
@@ -1405,8 +1408,8 @@ bool BGXFAM::OpenTempFile(PGLOBAL g)
if (Tfile == INVALID_HANDLE_VALUE) {
int rc = errno;
- snprintf(g->Message, sizeof(g->Message), MSG(OPEN_ERROR), rc, MODE_INSERT, tempname);
- strcat(g->Message, strerror(errno));
+ snprintf(g->Message, sizeof(g->Message), MSG(OPEN_ERROR)" %s", rc,
+ MODE_INSERT, tempname, strerror(errno));
return true;
} //endif Tfile
#endif // UNIX
diff --git a/storage/connect/filamgz.cpp b/storage/connect/filamgz.cpp
index 7e9597d6b75..d8ffa63beac 100644
--- a/storage/connect/filamgz.cpp
+++ b/storage/connect/filamgz.cpp
@@ -33,6 +33,8 @@
#include <fcntl.h>
#endif // !_WIN32
+#include <m_string.h>
+
/***********************************************************************/
/* Include application header files: */
/* global.h is header containing all global declarations. */
@@ -128,12 +130,13 @@ int GZFAM::GetFileLength(PGLOBAL g)
/***********************************************************************/
bool GZFAM::OpenTableFile(PGLOBAL g)
{
- char opmode[4], filename[_MAX_PATH];
- MODE mode = Tdbp->GetMode();
+ const char *opmode;
+ char filename[_MAX_PATH];
+ MODE mode = Tdbp->GetMode();
switch (mode) {
case MODE_READ:
- strcpy(opmode, "r");
+ opmode = "rb";
break;
case MODE_UPDATE:
/*****************************************************************/
@@ -147,7 +150,7 @@ bool GZFAM::OpenTableFile(PGLOBAL g)
DelRows = Cardinality(g);
// This will erase the entire file
- strcpy(opmode, "w");
+ opmode = "wb";
// Block = 0; // For ZBKFAM
// Last = Nrec; // For ZBKFAM
Tdbp->ResetSize();
@@ -158,7 +161,7 @@ bool GZFAM::OpenTableFile(PGLOBAL g)
break;
case MODE_INSERT:
- strcpy(opmode, "a+");
+ opmode = "a+b";
break;
default:
snprintf(g->Message, sizeof(g->Message), MSG(BAD_OPEN_MODE), mode);
@@ -170,13 +173,11 @@ bool GZFAM::OpenTableFile(PGLOBAL g)
/* Use specific zlib functions. */
/* Treat files as binary. */
/*********************************************************************/
- strcat(opmode, "b");
Zfile = gzopen(PlugSetPath(filename, To_File, Tdbp->GetPath()), opmode);
if (Zfile == NULL) {
- snprintf(g->Message, sizeof(g->Message), MSG(GZOPEN_ERROR),
- opmode, (int)errno, filename);
- strcat(strcat(g->Message, ": "), strerror(errno));
+ snprintf(g->Message, sizeof(g->Message), MSG(GZOPEN_ERROR) ": %s",
+ opmode, (int)errno, filename, strerror(errno));
return (mode == MODE_READ && errno == ENOENT)
? PushWarning(g, Tdbp) : true;
} // endif Zfile
diff --git a/storage/connect/filamtxt.cpp b/storage/connect/filamtxt.cpp
index 9ecc2293c48..9db890c5f36 100644
--- a/storage/connect/filamtxt.cpp
+++ b/storage/connect/filamtxt.cpp
@@ -38,6 +38,8 @@
#include <fcntl.h>
#endif // !_WIN32
+#include <m_string.h>
+
/***********************************************************************/
/* Include application header files: */
/* global.h is header containing all global declarations. */
@@ -593,7 +595,7 @@ bool DOSFAM::OpenTableFile(PGLOBAL g)
} // endswitch Mode
// For blocked I/O or for moving lines, open the table in binary
- strcat(opmode, (Bin) ? "b" : "t");
+ safe_strcat(opmode, sizeof(opmode), (Bin) ? "b" : "t");
// Now open the file stream
PlugSetPath(filename, To_File, Tdbp->GetPath());
@@ -1081,7 +1083,8 @@ bool DOSFAM::OpenTempFile(PGLOBAL g)
/* Open the temporary file, Spos is at the beginning of file. */
/*********************************************************************/
PlugSetPath(tempname, To_File, Tdbp->GetPath());
- strcat(PlugRemoveType(tempname, tempname), ".t");
+ PlugRemoveType(tempname, tempname);
+ safe_strcat(tempname, sizeof(tempname), ".t");
if (!(T_Stream = PlugOpenFile(g, tempname, "wb"))) {
if (trace(1))
@@ -1170,7 +1173,8 @@ int DOSFAM::RenameTempFile(PGLOBAL g)
if (!Abort) {
PlugSetPath(filename, To_File, Tdbp->GetPath());
- strcat(PlugRemoveType(filetemp, filename), ".ttt");
+ PlugRemoveType(filetemp, filename);
+ safe_strcat(filetemp, sizeof(filetemp), ".ttt");
remove(filetemp); // May still be there from previous error
if (rename(filename, filetemp)) { // Save file for security
diff --git a/storage/connect/filamvct.cpp b/storage/connect/filamvct.cpp
index f3e31895324..91a6772d961 100644
--- a/storage/connect/filamvct.cpp
+++ b/storage/connect/filamvct.cpp
@@ -42,6 +42,8 @@
#include <fcntl.h>
#endif // !_WIN32
+#include <m_string.h>
+
/***********************************************************************/
/* Include application header files: */
/* global.h is header containing all global declarations. */
@@ -194,7 +196,7 @@ int VCTFAM::GetBlockInfo(PGLOBAL g)
if (Header == 2)
{
PlugRemoveType(filename, filename);
- strncat(filename, ".blk", _MAX_PATH - strlen(filename));
+ safe_strcat(filename, sizeof(filename), ".blk");
}
if ((h = global_open(g, MSGID_CANNOT_OPEN, filename, O_RDONLY)) == -1
@@ -251,7 +253,7 @@ bool VCTFAM::SetBlockInfo(PGLOBAL g)
} else { // Header == 2
PlugRemoveType(filename, filename);
- strncat(filename, ".blk", _MAX_PATH - strlen(filename));
+ safe_strcat(filename, sizeof(filename), ".blk");
s= global_fopen(g, MSGID_CANNOT_OPEN, filename, "wb");
} // endif Header
@@ -586,7 +588,7 @@ bool VCTFAM::InitInsert(PGLOBAL g)
htrc("Exception %d: %s\n", n, g->Message);
rc = true;
} catch (const char *msg) {
- strncpy(g->Message, msg, sizeof(g->Message));
+ safe_strcpy(g->Message, sizeof(msg), msg);
rc = true;
} // end catch
@@ -890,8 +892,7 @@ bool VCTFAM::OpenTempFile(PGLOBAL g)
/*********************************************************************/
PlugSetPath(tempname, To_File, Tdbp->GetPath());
PlugRemoveType(tempname, tempname);
- strncat(tempname, ".t", _MAX_PATH - strlen(tempname));
-
+ safe_strcat(tempname, sizeof(tempname), ".t");
if (MaxBlk) {
if (MakeEmptyFile(g, tempname))
return true;
@@ -1562,7 +1563,7 @@ bool VCMFAM::InitInsert(PGLOBAL g)
htrc("Exception %d: %s\n", n, g->Message);
rc = true;
} catch (const char *msg) {
- strncpy(g->Message, msg, sizeof(g->Message));
+ safe_strcpy(g->Message, sizeof(g->Message), msg);
rc = true;
} // end catch
@@ -2082,10 +2083,10 @@ bool VECFAM::AllocateBuffer(PGLOBAL g)
// Allocate all that is needed to move lines and make Temp
if (UseTemp) {
Tempat = (char*)PlugSubAlloc(g, NULL, _MAX_PATH);
- strcpy(Tempat, Colfn);
+ safe_strcpy(Tempat, _MAX_PATH, Colfn);
PlugSetPath(Tempat, Tempat, Tdbp->GetPath());
PlugRemoveType(Tempat, Tempat);
- strncat(Tempat, ".t", _MAX_PATH - strlen(Tempat));
+ safe_strcat(Tempat, _MAX_PATH, ".t");
T_Fbs = (PFBLOCK *)PlugSubAlloc(g, NULL, Ncol * sizeof(PFBLOCK));
} // endif UseTemp
@@ -2460,7 +2461,7 @@ int VECFAM::RenameTempFile(PGLOBAL g)
snprintf(filename, _MAX_PATH, Colfn, i+1);
PlugSetPath(filename, filename, Tdbp->GetPath());
PlugRemoveType(filetemp, filename);
- strncat(filetemp, ".ttt", _MAX_PATH - strlen(filetemp));
+ safe_strcat(filetemp, sizeof(filetemp), ".ttt");
remove(filetemp); // May still be there from previous error
if (rename(filename, filetemp)) { // Save file for security
@@ -3221,7 +3222,7 @@ int BGVFAM::GetBlockInfo(PGLOBAL g)
if (Header == 2)
{
PlugRemoveType(filename, filename);
- strncat(filename, ".blk", _MAX_PATH - strlen(filename));
+ safe_strcat(filename, sizeof(filename), ".blk");
}
#if defined(_WIN32)
@@ -3300,7 +3301,7 @@ bool BGVFAM::SetBlockInfo(PGLOBAL g)
} else // Header == 2
{
PlugRemoveType(filename, filename);
- strncat(filename, ".blk", _MAX_PATH - strlen(filename));
+ safe_strcat(filename, sizeof(filename), ".blk");
}
if (h == INVALID_HANDLE_VALUE) {
@@ -3398,7 +3399,7 @@ bool BGVFAM::MakeEmptyFile(PGLOBAL g, PCSZ fn)
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS, NULL, rc, 0,
(LPTSTR)filename, sizeof(filename), NULL);
- strncat(g->Message, filename, sizeof(g->Message) - strlen(g->Message));
+ safe_strcat(g->Message, sizeof(g->Message), filename);
if (h != INVALID_HANDLE_VALUE)
CloseHandle(h);
@@ -3534,7 +3535,7 @@ bool BGVFAM::OpenTableFile(PGLOBAL g)
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS, NULL, rc, 0,
(LPTSTR)filename, sizeof(filename), NULL);
- strncat(g->Message, filename, sizeof(g->Message) - strlen(g->Message));
+ safe_strcat(g->Message, sizeof(g->Message), filename);
} // endif Hfile
if (trace(1))
@@ -3622,8 +3623,8 @@ bool BGVFAM::OpenTableFile(PGLOBAL g)
if (Hfile == INVALID_HANDLE_VALUE) {
rc = errno;
- snprintf(g->Message, sizeof(g->Message), MSG(OPEN_ERROR), rc, mode, filename);
- strncat(g->Message, strerror(errno), sizeof(g->Message) - strlen(g->Message));
+ snprintf(g->Message, sizeof(g->Message), MSG(OPEN_ERROR)"%s", rc, mode,
+ filename, strerror(errno));
} // endif Hfile
if (trace(1))
@@ -3967,7 +3968,7 @@ bool BGVFAM::OpenTempFile(PGLOBAL g)
tempname = (char*)PlugSubAlloc(g, NULL, _MAX_PATH);
PlugSetPath(tempname, To_File, Tdbp->GetPath());
PlugRemoveType(tempname, tempname);
- strncat(tempname, ".t", _MAX_PATH - strlen(tempname));
+ safe_strcat(tempname, _MAX_PATH, ".t");
if (!MaxBlk)
remove(tempname); // Be sure it does not exist yet
@@ -3986,7 +3987,7 @@ bool BGVFAM::OpenTempFile(PGLOBAL g)
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS, NULL, rc, 0,
(LPTSTR)tempname, _MAX_PATH, NULL);
- strncat(g->Message, tempname, sizeof(g->Message) - strlen(g->Message));
+ safe_strcat(g->Message, sizeof(g->Message), tempname);
return true;
} // endif Tfile
#else // UNIX
@@ -3996,8 +3997,8 @@ bool BGVFAM::OpenTempFile(PGLOBAL g)
if (Tfile == INVALID_HANDLE_VALUE) {
int rc = errno;
- snprintf(g->Message, sizeof(g->Message), MSG(OPEN_ERROR), rc, MODE_INSERT, tempname);
- strncat(g->Message, strerror(errno), sizeof(g->Message) - strlen(g->Message));
+ snprintf(g->Message, sizeof(g->Message), MSG(OPEN_ERROR) "%s", rc, MODE_INSERT,
+ tempname, strerror(errno));
return true;
} //endif Tfile
#endif // UNIX
diff --git a/storage/connect/filamzip.cpp b/storage/connect/filamzip.cpp
index 814503ae6f7..40926cd2ae7 100644
--- a/storage/connect/filamzip.cpp
+++ b/storage/connect/filamzip.cpp
@@ -29,6 +29,7 @@
#include <fcntl.h>
#endif // !_WIN32
#include <time.h>
+#include <m_string.h>
/***********************************************************************/
/* Include application header files: */
@@ -181,7 +182,8 @@ static bool ZipFiles(PGLOBAL g, ZIPUTIL *zutp, PCSZ pat, char *buf)
while (true) {
if (!(FileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
- strcat(strcat(strcpy(filename, drive), direc), FileData.cFileName);
+ snprintf(filename, sizeof(filename), "%s%s%s",
+ drive, direc, FileData.cFileName);
if (ZipFile(g, zutp, filename, FileData.cFileName, buf)) {
FindClose(hSearch);
@@ -217,7 +219,7 @@ static bool ZipFiles(PGLOBAL g, ZIPUTIL *zutp, PCSZ pat, char *buf)
struct dirent *entry;
_splitpath(filename, NULL, direc, pattern, ftype);
- strcat(pattern, ftype);
+ safe_strcat(pattern, sizeof(pattern), ftype);
// Start searching files in the target directory.
if (!(dir = opendir(direc))) {
@@ -226,7 +228,7 @@ static bool ZipFiles(PGLOBAL g, ZIPUTIL *zutp, PCSZ pat, char *buf)
} // endif dir
while ((entry = readdir(dir))) {
- strcat(strcpy(fn, direc), entry->d_name);
+ snprintf(fn, sizeof(fn), "%s%s", direc, entry->d_name);
if (lstat(fn, &fileinfo) < 0) {
snprintf(g->Message, sizeof(g->Message), "%s: %s", fn, strerror(errno));
@@ -240,7 +242,7 @@ static bool ZipFiles(PGLOBAL g, ZIPUTIL *zutp, PCSZ pat, char *buf)
if (fnmatch(pattern, entry->d_name, 0))
continue; // Not a match
- strcat(strcpy(filename, direc), entry->d_name);
+ snprintf(filename, sizeof(filename), "%s%s", direc, entry->d_name);
if (ZipFile(g, zutp, filename, entry->d_name, buf)) {
closedir(dir);
diff --git a/storage/connect/javaconn.cpp b/storage/connect/javaconn.cpp
index 0dc467aa7ee..3d1dfbc3f26 100644
--- a/storage/connect/javaconn.cpp
+++ b/storage/connect/javaconn.cpp
@@ -33,6 +33,8 @@
#define NODW
#endif // !_WIN32
+#include <m_string.h>
+
/***********************************************************************/
/* Required objects includes. */
/***********************************************************************/
@@ -231,15 +233,16 @@ bool JAVAConn::GetJVM(PGLOBAL g)
#if defined(_WIN32)
for (ntry = 0; !LibJvm && ntry < 3; ntry++) {
if (!ntry && JvmPath) {
- strcat(strcpy(soname, JvmPath), "\\jvm.dll");
+ snprintf(soname, sizeof(soname), "%s\\jvm.dll", JvmPath);
+
ntry = 3; // No other try
} else if (ntry < 2 && getenv("JAVA_HOME")) {
- strcpy(soname, getenv("JAVA_HOME"));
+ safe_strcpy(soname, sizeof(soname), getenv("JAVA_HOME"));
if (ntry == 1)
- strcat(soname, "\\jre");
+ safe_strcat(soname, sizeof(soname), "\\jre");
- strcat(soname, "\\bin\\client\\jvm.dll");
+ safe_strcat(soname, sizeof(soname), "\\bin\\client\\jvm.dll");
} else {
// Try to find it through the registry
char version[16];
@@ -247,11 +250,12 @@ bool JAVAConn::GetJVM(PGLOBAL g)
LONG rc;
DWORD BufferSize = 16;
- strcpy(soname, "jvm.dll"); // In case it fails
+ safe_strcpy(soname, sizeof(soname), "jvm.dll"); // In case it fails
if ((rc = RegGetValue(HKEY_LOCAL_MACHINE, javaKey, "CurrentVersion",
RRF_RT_ANY, NULL, (PVOID)&version, &BufferSize)) == ERROR_SUCCESS) {
- strcat(strcat(javaKey, "\\"), version);
+ safe_strcat(javaKey, sizeof(javaKey), "\\");
+ safe_strcat(javaKey, sizeof(javaKey), version);
BufferSize = sizeof(soname);
if ((rc = RegGetValue(HKEY_LOCAL_MACHINE, javaKey, "RuntimeLib",
@@ -272,11 +276,11 @@ bool JAVAConn::GetJVM(PGLOBAL g)
char buf[256];
DWORD rc = GetLastError();
- snprintf(g->Message, sizeof(g->Message), MSG(DLL_LOAD_ERROR), rc, soname);
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS, NULL, rc, 0,
(LPTSTR)buf, sizeof(buf), NULL);
- strcat(strcat(g->Message, ": "), buf);
+ snprintf(g->Message, sizeof(g->Message), MSG(DLL_LOAD_ERROR)": %s", rc,
+ soname, buf);
} else if (!(CreateJavaVM = (CRTJVM)GetProcAddress((HINSTANCE)LibJvm,
"JNI_CreateJavaVM"))) {
snprintf(g->Message, sizeof(g->Message), MSG(PROCADD_ERROR), GetLastError(), "JNI_CreateJavaVM");
@@ -301,13 +305,14 @@ bool JAVAConn::GetJVM(PGLOBAL g)
for (ntry = 0; !LibJvm && ntry < 2; ntry++) {
if (!ntry && JvmPath) {
- strcat(strcpy(soname, JvmPath), "/libjvm.so");
+ snprintf(soname, sizeof(soname), "%s/libjvm.so", JvmPath);
ntry = 2;
} else if (!ntry && getenv("JAVA_HOME")) {
// TODO: Replace i386 by a better guess
- strcat(strcpy(soname, getenv("JAVA_HOME")), "/jre/lib/i386/client/libjvm.so");
+ snprintf(soname, sizeof(soname), "%s/jre/lib/i386/client/libjvm.so",
+ getenv("JAVA_HOME"));
} else { // Will need LD_LIBRARY_PATH to be set
- strcpy(soname, "libjvm.so");
+ safe_strcpy(soname, sizeof(soname), "libjvm.so");
ntry = 2;
} // endelse
diff --git a/storage/connect/json.cpp b/storage/connect/json.cpp
index 0786c3139e1..9cce77d025a 100644
--- a/storage/connect/json.cpp
+++ b/storage/connect/json.cpp
@@ -10,6 +10,7 @@
/* Include relevant sections of the MariaDB header file. */
/***********************************************************************/
#include <my_global.h>
+#include <m_string.h>
/***********************************************************************/
/* Include application header files: */
@@ -270,7 +271,7 @@ PSZ Serialize(PGLOBAL g, PJSON jsp, char* fn, int pretty) {
jdp->dfp = GetDefaultPrec();
if (!jsp) {
- strcpy(g->Message, "Null json tree");
+ safe_strcpy(g->Message, sizeof(g->Message), "Null json tree");
throw 1;
} else if (!fn) {
// Serialize to a string
@@ -278,9 +279,8 @@ PSZ Serialize(PGLOBAL g, PJSON jsp, char* fn, int pretty) {
b = pretty == 1;
} else {
if (!(fs = fopen(fn, "wb"))) {
- snprintf(g->Message, sizeof(g->Message), MSG(OPEN_MODE_ERROR),
- "w", (int)errno, fn);
- strcat(strcat(g->Message, ": "), strerror(errno));
+ snprintf(g->Message, sizeof(g->Message), MSG(OPEN_MODE_ERROR) ": %s",
+ "w", (int)errno, fn, strerror(errno));
throw 2;
} else if (pretty >= 2) {
// Serialize to a pretty file
diff --git a/storage/connect/jsonudf.cpp b/storage/connect/jsonudf.cpp
index 1b5ff9ae0c4..d48489298ac 100644
--- a/storage/connect/jsonudf.cpp
+++ b/storage/connect/jsonudf.cpp
@@ -4753,7 +4753,7 @@ char *jbin_array(UDF_INIT *initid, UDF_ARGS *args, char *result,
if ((arp = (PJAR)JsonNew(g, TYPE_JAR)) &&
(bsp = JbinAlloc(g, args, initid->max_length, arp))) {
- strcat(bsp->Msg, " array");
+ safe_strcat(bsp->Msg, sizeof(bsp->Msg), " array");
for (uint i = 0; i < args->arg_count; i++)
arp->AddArrayValue(g, MakeValue(g, args, i));
@@ -4830,7 +4830,7 @@ char *jbin_array_add_values(UDF_INIT *initid, UDF_ARGS *args, char *result,
arp->InitArray(gb);
if ((bsp = JbinAlloc(g, args, initid->max_length, top))) {
- strcat(bsp->Msg, " array");
+ safe_strcat(bsp->Msg, sizeof(bsp->Msg), " array");
bsp->Jsp = arp;
} // endif bsp
@@ -5051,7 +5051,7 @@ char *jbin_object(UDF_INIT *initid, UDF_ARGS *args, char *result,
if ((bsp = JbinAlloc(g, args, initid->max_length, objp)))
- strcat(bsp->Msg, " object");
+ safe_strcat(bsp->Msg, sizeof(bsp->Msg), " object");
} else
bsp = NULL;
@@ -5107,7 +5107,7 @@ char *jbin_object_nonull(UDF_INIT *initid, UDF_ARGS *args, char *result,
objp->SetKeyValue(g, jvp, MakeKey(g, args, i));
if ((bsp = JbinAlloc(g, args, initid->max_length, objp)))
- strcat(bsp->Msg, " object");
+ safe_strcat(bsp->Msg, sizeof(bsp->Msg), " object");
} else
bsp = NULL;
@@ -5166,7 +5166,7 @@ char *jbin_object_key(UDF_INIT *initid, UDF_ARGS *args, char *result,
objp->SetKeyValue(g, MakeValue(g, args, i + 1), MakePSZ(g, args, i));
if ((bsp = JbinAlloc(g, args, initid->max_length, objp)))
- strcat(bsp->Msg, " object");
+ safe_strcat(bsp->Msg, sizeof(bsp->Msg), " object");
} else
bsp = NULL;
@@ -5388,7 +5388,7 @@ char *jbin_object_list(UDF_INIT *initid, UDF_ARGS *args, char *result,
} // endif CheckMemory
if ((bsp = JbinAlloc(g, args, initid->max_length, jarp)))
- strcat(bsp->Msg, " array");
+ safe_strcat(bsp->Msg, sizeof(bsp->Msg), " array");
// Keep result of constant function
g->Xchk = (initid->const_item) ? bsp : NULL;
@@ -5463,7 +5463,7 @@ char *jbin_get_item(UDF_INIT *initid, UDF_ARGS *args, char *result,
jsp = (jvp->GetJsp()) ? jvp->GetJsp() : JvalNew(g, TYPE_JVAL, jvp->GetValue(g));
if ((bsp = JbinAlloc(g, args, initid->max_length, jsp)))
- strcat(bsp->Msg, " item");
+ safe_strcat(bsp->Msg, sizeof(bsp->Msg), " item");
else
*error = 1;
@@ -5823,7 +5823,7 @@ char *jbin_file(UDF_INIT *initid, UDF_ARGS *args, char *result,
pretty = pty;
if ((bsp = JbinAlloc(g, args, len, jsp))) {
- strcat(bsp->Msg, " file");
+ safe_strcat(bsp->Msg, sizeof(bsp->Msg), " file");
bsp->Filename = fn;
bsp->Pretty = pretty;
} else {
@@ -6159,9 +6159,8 @@ char* JUP::UnprettyJsonFile(PGLOBAL g, char *fn, char *outfn, int lrecl) {
/* Parse the json file and allocate its tree structure. */
/*********************************************************************************/
if (!(fs = fopen(outfn, "wb"))) {
- snprintf(g->Message, sizeof(g->Message), MSG(OPEN_MODE_ERROR),
- "w", (int)errno, outfn);
- strcat(strcat(g->Message, ": "), strerror(errno));
+ snprintf(g->Message, sizeof(g->Message), MSG(OPEN_MODE_ERROR)": %s",
+ "w", (int)errno, outfn, strerror(errno));
CloseMemMap(mm.memory, len);
return NULL;
} // endif fs
diff --git a/storage/connect/myconn.cpp b/storage/connect/myconn.cpp
index e5ea1ac52ae..7a4c2f897a0 100644
--- a/storage/connect/myconn.cpp
+++ b/storage/connect/myconn.cpp
@@ -405,18 +405,20 @@ PQRYRES SrcColumns(PGLOBAL g, const char *host, const char *db,
port = mysqld_port;
if (!strnicmp(srcdef, "select ", 7) || strstr(srcdef, "%s")) {
- query = (char *)PlugSubAlloc(g, NULL, strlen(srcdef) + 10);
+ size_t query_sz = strlen(srcdef) + 10;
+ query = (char *)PlugSubAlloc(g, NULL, query_sz);
if ((p= strstr(srcdef, "%s")))
{
/* Replace %s with 1=1 */
- sprintf(query, "%.*s1=1%s", (int) (p - srcdef), srcdef, p + 2); // dummy where clause
+ snprintf(query, query_sz, "%.*s1=1%s",
+ (int) (p - srcdef), srcdef, p + 2); // dummy where clause
}
- else
- strcpy(query, srcdef);
+ else
+ safe_strcpy(query, query_sz, srcdef);
if (!strnicmp(srcdef, "select ", 7))
- strcat(query, " LIMIT 0");
+ safe_strcat(query, query_sz, " LIMIT 0");
} else
query = (char *)srcdef;