Skip to content

Commit

Permalink
Use memory safe snprintf() in Connect Engine and elsewhere (#2210)
Browse files Browse the repository at this point in the history
Continue with similar changes as done in 19af189 to replace sprintf(buf, ...)
with snprintf(buf, sizeof(buf), ...), specifically in the "easy" cases where buf
is allocated with a size known at compile time.

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, Inc.
  • Loading branch information
Chaloff authored Sep 28, 2022
1 parent b2cfcf1 commit 9de9f10
Show file tree
Hide file tree
Showing 13 changed files with 70 additions and 61 deletions.
14 changes: 7 additions & 7 deletions client/mysqlshow.c
Original file line number Diff line number Diff line change
Expand Up @@ -449,7 +449,7 @@ list_dbs(MYSQL *mysql,const char *wild)
MYSQL_RES *tresult = mysql_list_tables(mysql,(char*)NULL);
if (mysql_affected_rows(mysql) > 0)
{
sprintf(tables,"%6lu",(ulong) mysql_affected_rows(mysql));
snprintf(tables, sizeof(tables), "%6lu",(ulong) mysql_affected_rows(mysql));
rowcount = 0;
if (opt_verbose > 1)
{
Expand All @@ -470,13 +470,13 @@ list_dbs(MYSQL *mysql,const char *wild)
}
}
}
sprintf(rows,"%12lu",rowcount);
snprintf(rows, sizeof(rows), "%12lu", rowcount);
}
}
else
{
sprintf(tables,"%6d",0);
sprintf(rows,"%12d",0);
snprintf(tables, sizeof(tables), "%6d" ,0);
snprintf(rows, sizeof(rows), "%12d", 0);
}
mysql_free_result(tresult);
}
Expand Down Expand Up @@ -594,7 +594,7 @@ list_tables(MYSQL *mysql,const char *db,const char *table)
}
else
{
sprintf(fields,"%8u",(uint) mysql_num_fields(rresult));
snprintf(fields, sizeof(fields), "%8u", (uint) mysql_num_fields(rresult));
mysql_free_result(rresult);

if (opt_verbose > 1)
Expand All @@ -610,10 +610,10 @@ list_tables(MYSQL *mysql,const char *db,const char *table)
rowcount += (unsigned long) strtoull(rrow[0], (char**) 0, 10);
mysql_free_result(rresult);
}
sprintf(rows,"%10lu",rowcount);
snprintf(rows, sizeof(rows), "%10lu", rowcount);
}
else
sprintf(rows,"%10d",0);
snprintf(rows, sizeof(rows), "%10d", 0);
}
}
}
Expand Down
60 changes: 30 additions & 30 deletions sql/sql_analyse.cc
Original file line number Diff line number Diff line change
Expand Up @@ -412,7 +412,7 @@ void field_real::add()

if ((decs = decimals()) >= FLOATING_POINT_DECIMALS)
{
length= sprintf(buff, "%g", num);
length= snprintf(buff, sizeof(buff), "%g", num);
if (rint(num) != num)
max_notzero_dec_len = 1;
}
Expand All @@ -423,7 +423,7 @@ void field_real::add()
snprintf(buff, sizeof(buff)-1, "%-.*f", (int) decs, num);
length = (uint) strlen(buff);
#else
length= sprintf(buff, "%-.*f", (int) decs, num);
length= snprintf(buff, sizeof(buff), "%-.*f", (int) decs, num);
#endif

// We never need to check further than this
Expand Down Expand Up @@ -810,32 +810,32 @@ void field_str::get_opt_type(String *answer, ha_rows total_rows)
if (can_be_still_num)
{
if (num_info.is_float)
sprintf(buff, "DOUBLE"); // number was like 1e+50... TODO:
snprintf(buff, sizeof(buff), "DOUBLE"); // number was like 1e+50... TODO:
else if (num_info.decimals) // DOUBLE(%d,%d) sometime
{
if (num_info.dval > -FLT_MAX && num_info.dval < FLT_MAX)
sprintf(buff, "FLOAT(%d,%d)", (num_info.integers + num_info.decimals), num_info.decimals);
snprintf(buff, sizeof(buff), "FLOAT(%d,%d)", (num_info.integers + num_info.decimals), num_info.decimals);
else
sprintf(buff, "DOUBLE(%d,%d)", (num_info.integers + num_info.decimals), num_info.decimals);
snprintf(buff, sizeof(buff), "DOUBLE(%d,%d)", (num_info.integers + num_info.decimals), num_info.decimals);
}
else if (ev_num_info.llval >= -128 &&
ev_num_info.ullval <=
(ulonglong) (ev_num_info.llval >= 0 ? 255 : 127))
sprintf(buff, "TINYINT(%d)", num_info.integers);
snprintf(buff, sizeof(buff), "TINYINT(%d)", num_info.integers);
else if (ev_num_info.llval >= INT_MIN16 &&
ev_num_info.ullval <= (ulonglong) (ev_num_info.llval >= 0 ?
UINT_MAX16 : INT_MAX16))
sprintf(buff, "SMALLINT(%d)", num_info.integers);
snprintf(buff, sizeof(buff), "SMALLINT(%d)", num_info.integers);
else if (ev_num_info.llval >= INT_MIN24 &&
ev_num_info.ullval <= (ulonglong) (ev_num_info.llval >= 0 ?
UINT_MAX24 : INT_MAX24))
sprintf(buff, "MEDIUMINT(%d)", num_info.integers);
snprintf(buff, sizeof(buff), "MEDIUMINT(%d)", num_info.integers);
else if (ev_num_info.llval >= INT_MIN32 &&
ev_num_info.ullval <= (ulonglong) (ev_num_info.llval >= 0 ?
UINT_MAX32 : INT_MAX32))
sprintf(buff, "INT(%d)", num_info.integers);
snprintf(buff, sizeof(buff), "INT(%d)", num_info.integers);
else
sprintf(buff, "BIGINT(%d)", num_info.integers);
snprintf(buff, sizeof(buff), "BIGINT(%d)", num_info.integers);
answer->append(buff, (uint) strlen(buff));
if (ev_num_info.llval >= 0 && ev_num_info.min_dval >= 0)
answer->append(STRING_WITH_LEN(" UNSIGNED"));
Expand All @@ -853,12 +853,12 @@ void field_str::get_opt_type(String *answer, ha_rows total_rows)
}
else if ((max_length * (total_rows - nulls)) < (sum + total_rows))
{
sprintf(buff, "CHAR(%d)", (int) max_length);
snprintf(buff, sizeof(buff), "CHAR(%d)", (int) max_length);
answer->append(buff, (uint) strlen(buff));
}
else
{
sprintf(buff, "VARCHAR(%d)", (int) max_length);
snprintf(buff, sizeof(buff), "VARCHAR(%d)", (int) max_length);
answer->append(buff, (uint) strlen(buff));
}
}
Expand Down Expand Up @@ -897,18 +897,18 @@ void field_real::get_opt_type(String *answer,
0 : (item->decimals + 1));

if (min_arg >= -128 && max_arg <= (min_arg >= 0 ? 255 : 127))
sprintf(buff, "TINYINT(%d)", len);
snprintf(buff, sizeof(buff), "TINYINT(%d)", len);
else if (min_arg >= INT_MIN16 && max_arg <= (min_arg >= 0 ?
UINT_MAX16 : INT_MAX16))
sprintf(buff, "SMALLINT(%d)", len);
snprintf(buff, sizeof(buff), "SMALLINT(%d)", len);
else if (min_arg >= INT_MIN24 && max_arg <= (min_arg >= 0 ?
UINT_MAX24 : INT_MAX24))
sprintf(buff, "MEDIUMINT(%d)", len);
snprintf(buff, sizeof(buff), "MEDIUMINT(%d)", len);
else if (min_arg >= INT_MIN32 && max_arg <= (min_arg >= 0 ?
UINT_MAX32 : INT_MAX32))
sprintf(buff, "INT(%d)", len);
snprintf(buff, sizeof(buff), "INT(%d)", len);
else
sprintf(buff, "BIGINT(%d)", len);
snprintf(buff, sizeof(buff), "BIGINT(%d)", len);
answer->append(buff, (uint) strlen(buff));
if (min_arg >= 0)
answer->append(STRING_WITH_LEN(" UNSIGNED"));
Expand All @@ -923,10 +923,10 @@ void field_real::get_opt_type(String *answer,
else
{
if (min_arg >= -FLT_MAX && max_arg <= FLT_MAX)
sprintf(buff, "FLOAT(%d,%d)", (int) max_length - (item->decimals + 1) + max_notzero_dec_len,
snprintf(buff, sizeof(buff), "FLOAT(%d,%d)", (int) max_length - (item->decimals + 1) + max_notzero_dec_len,
max_notzero_dec_len);
else
sprintf(buff, "DOUBLE(%d,%d)", (int) max_length - (item->decimals + 1) + max_notzero_dec_len,
snprintf(buff, sizeof(buff), "DOUBLE(%d,%d)", (int) max_length - (item->decimals + 1) + max_notzero_dec_len,
max_notzero_dec_len);
answer->append(buff, (uint) strlen(buff));
}
Expand All @@ -945,18 +945,18 @@ void field_longlong::get_opt_type(String *answer,
char buff[MAX_FIELD_WIDTH];

if (min_arg >= -128 && max_arg <= (min_arg >= 0 ? 255 : 127))
sprintf(buff, "TINYINT(%d)", (int) max_length);
snprintf(buff, sizeof(buff), "TINYINT(%d)", (int) max_length);
else if (min_arg >= INT_MIN16 && max_arg <= (min_arg >= 0 ?
UINT_MAX16 : INT_MAX16))
sprintf(buff, "SMALLINT(%d)", (int) max_length);
snprintf(buff, sizeof(buff), "SMALLINT(%d)", (int) max_length);
else if (min_arg >= INT_MIN24 && max_arg <= (min_arg >= 0 ?
UINT_MAX24 : INT_MAX24))
sprintf(buff, "MEDIUMINT(%d)", (int) max_length);
snprintf(buff, sizeof(buff), "MEDIUMINT(%d)", (int) max_length);
else if (min_arg >= INT_MIN32 && max_arg <= (min_arg >= 0 ?
UINT_MAX32 : INT_MAX32))
sprintf(buff, "INT(%d)", (int) max_length);
snprintf(buff, sizeof(buff), "INT(%d)", (int) max_length);
else
sprintf(buff, "BIGINT(%d)", (int) max_length);
snprintf(buff, sizeof(buff), "BIGINT(%d)", (int) max_length);
answer->append(buff, (uint) strlen(buff));
if (min_arg >= 0)
answer->append(STRING_WITH_LEN(" UNSIGNED"));
Expand All @@ -976,15 +976,15 @@ void field_ulonglong::get_opt_type(String *answer,
char buff[MAX_FIELD_WIDTH];

if (max_arg < 256)
sprintf(buff, "TINYINT(%d) UNSIGNED", (int) max_length);
snprintf(buff, sizeof(buff), "TINYINT(%d) UNSIGNED", (int) max_length);
else if (max_arg <= ((2 * INT_MAX16) + 1))
sprintf(buff, "SMALLINT(%d) UNSIGNED", (int) max_length);
snprintf(buff, sizeof(buff), "SMALLINT(%d) UNSIGNED", (int) max_length);
else if (max_arg <= ((2 * INT_MAX24) + 1))
sprintf(buff, "MEDIUMINT(%d) UNSIGNED", (int) max_length);
snprintf(buff, sizeof(buff), "MEDIUMINT(%d) UNSIGNED", (int) max_length);
else if (max_arg < (((ulonglong) 1) << 32))
sprintf(buff, "INT(%d) UNSIGNED", (int) max_length);
snprintf(buff, sizeof(buff), "INT(%d) UNSIGNED", (int) max_length);
else
sprintf(buff, "BIGINT(%d) UNSIGNED", (int) max_length);
snprintf(buff, sizeof(buff), "BIGINT(%d) UNSIGNED", (int) max_length);
// if item is FIELD_ITEM, it _must_be_ Field_num in this class
answer->append(buff, (uint) strlen(buff));
if (item->type() == Item::FIELD_ITEM &&
Expand All @@ -1005,7 +1005,7 @@ void field_decimal::get_opt_type(String *answer,
my_decimal_set_zero(&zero);
my_bool is_unsigned= (my_decimal_cmp(&zero, &min_arg) >= 0);

length= sprintf(buff, "DECIMAL(%d, %d)",
length= snprintf(buff, sizeof(buff), "DECIMAL(%d, %d)",
(int) (max_length - (item->decimals ? 1 : 0)),
item->decimals);
if (is_unsigned)
Expand Down
2 changes: 1 addition & 1 deletion sql/sql_repl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4032,7 +4032,7 @@ bool mysql_show_binlog_events(THD* thd)
binlog_size= s.st_size;
if (lex_mi->pos > binlog_size)
{
sprintf(errmsg_buf, "Invalid pos specified. Requested from pos:%llu is "
snprintf(errmsg_buf, sizeof(errmsg_buf), "Invalid pos specified. Requested from pos:%llu is "
"greater than actual file size:%lu\n", lex_mi->pos,
(ulong)s.st_size);
errmsg= errmsg_buf;
Expand Down
4 changes: 2 additions & 2 deletions storage/connect/bsonudf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1144,7 +1144,7 @@ my_bool BJNX::LocateArray(PGLOBAL g, PBVAL jarp)

for (int i = 0; i < n && !Found; i++) {
Jp->N = m;
sprintf(s, "[%d]", i + B);
snprintf(s, sizeof(s), "[%d]", i + B);

if (Jp->WriteStr(s))
return true;
Expand Down Expand Up @@ -1438,7 +1438,7 @@ my_bool BJNX::AddPath(void)

for (int i = 0; i <= I; i++) {
if (Jpnp[i].Type == TYPE_JAR) {
sprintf(s, "[%d]", Jpnp[i].N + B);
snprintf(s, sizeof(s), "[%d]", Jpnp[i].N + B);

if (Jp->WriteStr(s))
return true;
Expand Down
2 changes: 2 additions & 0 deletions storage/connect/global.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
#include <time.h> /* time_t type declaration */
#include <setjmp.h> /* Long jump declarations */

#define ROUNDUP_TO_8(num) (((num + 7) / 8) * 8)

#if defined(_WIN32) && !defined(NOEX)
#define DllExport __declspec( dllexport )
#else // !_WIN32
Expand Down
10 changes: 8 additions & 2 deletions storage/connect/jdbconn.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -451,8 +451,14 @@ PQRYRES JDBCSrcCols(PGLOBAL g, PCSZ src, PJPARM sjp)

if (strstr(src, "%s")) {
// Place holder for an eventual where clause
sqry = (char*)PlugSubAlloc(g, NULL, strlen(src) + 2);
sprintf(sqry, src, "1=1"); // dummy where clause
size_t sqry_size = strlen(src) + 2;
sqry = (char*)PlugSubAlloc(g, NULL, sqry_size);
// Function PlugSubAlloc(...) recalculate string size
// while allocate memory - it rounds size up size to multiple of 8
// we need to know the real allocated size
// to use it in sprintf(...)
const int sqry_real_allocated_size = ROUNDUP_TO_8(sqry_size);
snprintf(sqry, sqry_real_allocated_size, src, "1=1"); // dummy where clause
} else
sqry = (char*)src;

Expand Down
6 changes: 3 additions & 3 deletions storage/connect/json.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1023,13 +1023,13 @@ bool JDOC::SerializeValue(PJVAL jvp)
case TYPE_DTM:
return js->Escape(jvp->Strp);
case TYPE_INTG:
sprintf(buf, "%d", jvp->N);
snprintf(buf, sizeof(buf), "%d", jvp->N);
return js->WriteStr(buf);
case TYPE_BINT:
sprintf(buf, "%lld", jvp->LLn);
snprintf(buf, sizeof(buf), "%lld", jvp->LLn);
return js->WriteStr(buf);
case TYPE_DBL: // dfp to limit to the default number of decimals
sprintf(buf, "%.*f", MY_MIN(jvp->Nd, dfp), jvp->F);
snprintf(buf, sizeof(buf), "%.*f", MY_MIN(jvp->Nd, dfp), jvp->F);
return js->WriteStr(buf);
case TYPE_NULL:
return js->WriteStr("null");
Expand Down
4 changes: 2 additions & 2 deletions storage/connect/jsonudf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -908,7 +908,7 @@ my_bool JSNX::LocateArray(PGLOBAL g, PJAR jarp)

for (int i = 0; i < jarp->size() && !Found; i++) {
Jp->N = m;
sprintf(s, "[%d]", i + B);
snprintf(s, sizeof(s), "[%d]", i + B);

if (Jp->WriteStr(s))
return true;
Expand Down Expand Up @@ -1189,7 +1189,7 @@ my_bool JSNX::AddPath(void) {

for (int i = 0; i <= I; i++) {
if (Jpnp[i].Type == TYPE_JAR) {
sprintf(s, "[%d]", Jpnp[i].N + B);
snprintf(s, sizeof(s), "[%d]", Jpnp[i].N + B);

if (Jp->WriteStr(s))
return true;
Expand Down
17 changes: 9 additions & 8 deletions storage/connect/plugutil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -371,13 +371,13 @@ char *PlugReadMessage(PGLOBAL g, int mid, char *m)
PlugSetPath(msgfile, NULL, buff, msg_path);

if (!(mfile = fopen(msgfile, "rt"))) {
sprintf(stmsg, "Fail to open message file %s", msgfile);
snprintf(stmsg, sizeof(stmsg), "Fail to open message file %s", msgfile);
goto err;
} // endif mfile

for (;;)
if (!fgets(buff, 256, mfile)) {
sprintf(stmsg, "Cannot get message %d %s", mid, SVP(m));
snprintf(stmsg, sizeof(stmsg), "Cannot get message %d %s", mid, SVP(m));
goto fin;
} else
if (atoi(buff) == mid)
Expand All @@ -386,7 +386,7 @@ char *PlugReadMessage(PGLOBAL g, int mid, char *m)
if (sscanf(buff, " %*d %.31s \"%.255[^\"]", msgid, stmsg) < 2) {
// Old message file
if (!sscanf(buff, " %*d \"%.255[^\"]", stmsg)) {
sprintf(stmsg, "Bad message file for %d %s", mid, SVP(m));
snprintf(stmsg, sizeof(stmsg), "Bad message file for %d %s", mid, SVP(m));
goto fin;
} else
m = NULL;
Expand Down Expand Up @@ -425,17 +425,18 @@ char *PlugGetMessage(PGLOBAL g, int mid)

if (n == 0) {
DWORD rc = GetLastError();
msg = (char*)PlugSubAlloc(g, NULL, 512); // Extend buf allocation
n = sprintf(msg, "Message %d, rc=%d: ", mid, rc);
const int BUF_SIZE= 512;
msg = (char*)PlugSubAlloc(g, NULL, BUF_SIZE); // Extend buf allocation
n = snprintf(msg, BUF_SIZE, "Message %d, rc=%d: ", mid, rc);
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS, NULL, rc, 0,
(LPTSTR)(msg + n), 512 - n, NULL);
(LPTSTR)(msg + n), BUF_SIZE - n, NULL);
return msg;
} // endif n

#else // ALL
if (!GetRcString(mid, stmsg, 200))
sprintf(stmsg, "Message %d not found", mid);
snprintf(stmsg, sizeof(stmsg) "Message %d not found", mid);
#endif // ALL

if (g) {
Expand Down Expand Up @@ -564,7 +565,7 @@ void *PlugSubAlloc(PGLOBAL g, void *memp, size_t size)
/*******************************************************************/
memp = g->Sarea;

size = ((size + 7) / 8) * 8; /* Round up size to multiple of 8 */
size = ROUNDUP_TO_8(size); /* Round up size to multiple of 8 */
pph = (PPOOLHEADER)memp;

if (trace(16))
Expand Down
4 changes: 2 additions & 2 deletions storage/connect/tabbson.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -477,7 +477,7 @@ bool BSONDISC::Find(PGLOBAL g, PBVAL jvp, PCSZ key, int j)
n = sizeof(fmt) - (strlen(fmt) + 1);

if (!tdp->Xcol || stricmp(tdp->Xcol, key)) {
sprintf(buf, "%d", k);
snprintf(buf, sizeof(buf), "%d", k);

if (tdp->Uri) {
strncat(strncat(fmt, sep, n), buf, n - strlen(sep));
Expand Down Expand Up @@ -798,7 +798,7 @@ void BCUTIL::SetJsonValue(PGLOBAL g, PVAL vp, PBVAL jvp)

break;
default:
sprintf(G->Message, "Unsupported column type %d", vp->GetType());
snprintf(G->Message, sizeof(G->Message), "Unsupported column type %d", vp->GetType());
throw 888;
} // endswitch Type

Expand Down
2 changes: 1 addition & 1 deletion storage/connect/tabwmi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -810,7 +810,7 @@ void WMICOL::ReadColumn(PGLOBAL g)
char buf[24];
int rc = VariantTimeToSystemTime(Prop.date, &stm);

sprintf(buf, "%02d/%02d/%d %02d:%02d:%02d",
snprintf(buf, sizeof(buf), "%02d/%02d/%d %02d:%02d:%02d",
stm.wDay, stm.wMonth, stm.wYear,
stm.wHour, stm.wMinute, stm.wSecond);
Value->SetValue_psz(buf);
Expand Down
2 changes: 1 addition & 1 deletion storage/connect/valblk.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -604,7 +604,7 @@ int TYPBLK<TYPE>::GetMaxLength(void)
int i, n, m;

for (i = n = 0; i < Nval; i++) {
m = sprintf(buf, Fmt, UnalignedRead(i));
m = snprintf(buf, sizeof(buf), Fmt, UnalignedRead(i));
n = MY_MAX(n, m);
} // endfor i

Expand Down
Loading

0 comments on commit 9de9f10

Please sign in to comment.