mirror of
https://github.com/MariaDB/server.git
synced 2025-08-08 11:22:35 +03:00
Use memory safe snprintf() in Connect Engine
This commit replaces sprintf(buf, ...) with snprintf(buf, sizeof(buf), ...), specifically in the "easy" cases where buf is allocated with a size known at compile time. The changes make sure we are not write outside array/string bounds which will lead to undefined behaviour. In case the code is trying to write outside bounds - safe version of functions simply cut the string messages so we process this gracefully. 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. bsonudf.cpp warnings cleanup by Daniel Black Reviewer: Daniel Black
This commit is contained in:
committed by
Daniel Black
parent
95eb5e5a12
commit
19af1890b5
@@ -199,7 +199,7 @@ bool DOSDEF::GetOptFileName(PGLOBAL g, char *filename)
|
||||
case RECFM_CSV: ftype = ".cop"; break;
|
||||
case RECFM_DBF: ftype = ".dbp"; break;
|
||||
default:
|
||||
sprintf(g->Message, MSG(INVALID_FTYPE), Recfm);
|
||||
snprintf(g->Message, sizeof(g->Message), MSG(INVALID_FTYPE), Recfm);
|
||||
return true;
|
||||
} // endswitch Ftype
|
||||
|
||||
@@ -270,7 +270,7 @@ bool DOSDEF::DeleteIndexFile(PGLOBAL g, PIXDEF pxdf)
|
||||
case RECFM_CSV: ftype = ".cnx"; break;
|
||||
case RECFM_DBF: ftype = ".dbx"; break;
|
||||
default:
|
||||
sprintf(g->Message, MSG(BAD_RECFM_VAL), Recfm);
|
||||
snprintf(g->Message, sizeof(g->Message), MSG(BAD_RECFM_VAL), Recfm);
|
||||
return true;
|
||||
} // endswitch Ftype
|
||||
|
||||
@@ -323,7 +323,7 @@ bool DOSDEF::DeleteIndexFile(PGLOBAL g, PIXDEF pxdf)
|
||||
} // endif sep
|
||||
|
||||
if (rc)
|
||||
sprintf(g->Message, MSG(DEL_FILE_ERR), filename);
|
||||
snprintf(g->Message, sizeof(g->Message), MSG(DEL_FILE_ERR), filename);
|
||||
|
||||
return rc; // Return true if error
|
||||
} // end of DeleteIndexFile
|
||||
@@ -405,7 +405,7 @@ PTDB DOSDEF::GetTable(PGLOBAL g, MODE mode)
|
||||
} // endif Recfm
|
||||
|
||||
#else // !ZIP_SUPPORT
|
||||
sprintf(g->Message, MSG(NO_FEAT_SUPPORT), "ZIP");
|
||||
snprintf(g->Message, sizeof(g->Message), MSG(NO_FEAT_SUPPORT), "ZIP");
|
||||
return NULL;
|
||||
#endif // !ZIP_SUPPORT
|
||||
} else if (Recfm != RECFM_VAR && Compressed < 2) {
|
||||
@@ -417,7 +417,7 @@ PTDB DOSDEF::GetTable(PGLOBAL g, MODE mode)
|
||||
#if defined(GZ_SUPPORT)
|
||||
txfp = new(g) GZXFAM(this);
|
||||
#else // !GZ_SUPPORT
|
||||
sprintf(g->Message, MSG(NO_FEAT_SUPPORT), "GZ");
|
||||
snprintf(g->Message, sizeof(g->Message), MSG(NO_FEAT_SUPPORT), "GZ");
|
||||
return NULL;
|
||||
#endif // !GZ_SUPPORT
|
||||
} else
|
||||
@@ -433,7 +433,7 @@ PTDB DOSDEF::GetTable(PGLOBAL g, MODE mode)
|
||||
txfp = new(g) ZLBFAM(this);
|
||||
|
||||
#else // !GZ_SUPPORT
|
||||
sprintf(g->Message, MSG(NO_FEAT_SUPPORT), "GZ");
|
||||
snprintf(g->Message, sizeof(g->Message), MSG(NO_FEAT_SUPPORT), "GZ");
|
||||
return NULL;
|
||||
#endif // !GZ_SUPPORT
|
||||
} else if (map)
|
||||
@@ -468,7 +468,7 @@ PTDB DOSDEF::GetTable(PGLOBAL g, MODE mode)
|
||||
((PZLBFAM)txfp)->SetOptimized(To_Pos != NULL);
|
||||
} // endelse
|
||||
#else
|
||||
sprintf(g->Message, MSG(NO_FEAT_SUPPORT), "GZ");
|
||||
snprintf(g->Message, sizeof(g->Message), MSG(NO_FEAT_SUPPORT), "GZ");
|
||||
return NULL;
|
||||
#endif
|
||||
} else
|
||||
@@ -912,7 +912,7 @@ bool TDBDOS::SaveBlockValues(PGLOBAL g)
|
||||
return true;
|
||||
|
||||
if (!(opfile = fopen(filename, "wb"))) {
|
||||
sprintf(g->Message, MSG(OPEN_MODE_ERROR),
|
||||
snprintf(g->Message, sizeof(g->Message), MSG(OPEN_MODE_ERROR),
|
||||
"wb", (int)errno, filename);
|
||||
strcat(strcat(g->Message, ": "), strerror(errno));
|
||||
|
||||
@@ -933,12 +933,12 @@ bool TDBDOS::SaveBlockValues(PGLOBAL g)
|
||||
n[0] = Txfp->Last; n[1] = lg; n[2] = Txfp->Nrec; n[3] = Txfp->Block;
|
||||
|
||||
if (fwrite(n, sizeof(int), NZ, opfile) != NZ) {
|
||||
sprintf(g->Message, MSG(OPT_HEAD_WR_ERR), strerror(errno));
|
||||
snprintf(g->Message, sizeof(g->Message), MSG(OPT_HEAD_WR_ERR), strerror(errno));
|
||||
rc = true;
|
||||
} // endif size
|
||||
|
||||
if (fwrite(Txfp->BlkPos, lg, block, opfile) != block) {
|
||||
sprintf(g->Message, MSG(OPTBLK_WR_ERR), strerror(errno));
|
||||
snprintf(g->Message, sizeof(g->Message), MSG(OPTBLK_WR_ERR), strerror(errno));
|
||||
rc = true;
|
||||
} // endif size
|
||||
|
||||
@@ -961,17 +961,17 @@ bool TDBDOS::SaveBlockValues(PGLOBAL g)
|
||||
n[4] = ndv; n[5] = nbm;
|
||||
|
||||
if (fwrite(n, sizeof(int), NZ + 2, opfile) != NZ + 2) {
|
||||
sprintf(g->Message, MSG(OPT_HEAD_WR_ERR), strerror(errno));
|
||||
snprintf(g->Message, sizeof(g->Message), MSG(OPT_HEAD_WR_ERR), strerror(errno));
|
||||
rc = true;
|
||||
} // endif size
|
||||
|
||||
if (fwrite(colp->Dval->GetValPointer(), lg, ndv, opfile) != ndv) {
|
||||
sprintf(g->Message, MSG(OPT_DVAL_WR_ERR), strerror(errno));
|
||||
snprintf(g->Message, sizeof(g->Message), MSG(OPT_DVAL_WR_ERR), strerror(errno));
|
||||
rc = true;
|
||||
} // endif size
|
||||
|
||||
if (fwrite(colp->Bmap->GetValPointer(), sizeof(int), nbk, opfile) != nbk) {
|
||||
sprintf(g->Message, MSG(OPT_BMAP_WR_ERR), strerror(errno));
|
||||
snprintf(g->Message, sizeof(g->Message), MSG(OPT_BMAP_WR_ERR), strerror(errno));
|
||||
rc = true;
|
||||
} // endif size
|
||||
|
||||
@@ -979,17 +979,17 @@ bool TDBDOS::SaveBlockValues(PGLOBAL g)
|
||||
n[0] = colp->Index; n[1] = lg; n[2] = Txfp->Nrec; n[3] = block;
|
||||
|
||||
if (fwrite(n, sizeof(int), NZ, opfile) != NZ) {
|
||||
sprintf(g->Message, MSG(OPT_HEAD_WR_ERR), strerror(errno));
|
||||
snprintf(g->Message, sizeof(g->Message), MSG(OPT_HEAD_WR_ERR), strerror(errno));
|
||||
rc = true;
|
||||
} // endif size
|
||||
|
||||
if (fwrite(colp->Min->GetValPointer(), lg, block, opfile) != block) {
|
||||
sprintf(g->Message, MSG(OPT_MIN_WR_ERR), strerror(errno));
|
||||
snprintf(g->Message, sizeof(g->Message), MSG(OPT_MIN_WR_ERR), strerror(errno));
|
||||
rc = true;
|
||||
} // endif size
|
||||
|
||||
if (fwrite(colp->Max->GetValPointer(), lg, block, opfile) != block) {
|
||||
sprintf(g->Message, MSG(OPT_MAX_WR_ERR), strerror(errno));
|
||||
snprintf(g->Message, sizeof(g->Message), MSG(OPT_MAX_WR_ERR), strerror(errno));
|
||||
rc = true;
|
||||
} // endif size
|
||||
|
||||
@@ -1095,12 +1095,12 @@ bool TDBDOS::GetBlockValues(PGLOBAL g)
|
||||
lg = sizeof(int);
|
||||
|
||||
if (fread(n, sizeof(int), NZ, opfile) != NZ) {
|
||||
sprintf(g->Message, MSG(OPT_HEAD_RD_ERR), strerror(errno));
|
||||
snprintf(g->Message, sizeof(g->Message), MSG(OPT_HEAD_RD_ERR), strerror(errno));
|
||||
goto err;
|
||||
} // endif size
|
||||
|
||||
if (n[1] != lg || n[2] != nrec) {
|
||||
sprintf(g->Message, MSG(OPT_NOT_MATCH), filename);
|
||||
snprintf(g->Message, sizeof(g->Message), MSG(OPT_NOT_MATCH), filename);
|
||||
goto err;
|
||||
} // endif
|
||||
|
||||
@@ -1111,7 +1111,7 @@ bool TDBDOS::GetBlockValues(PGLOBAL g)
|
||||
defp->To_Pos = (int*)PlugSubAlloc(g, NULL, blk * lg);
|
||||
|
||||
if (fread(defp->To_Pos, lg, blk, opfile) != blk) {
|
||||
sprintf(g->Message, MSG(OPTBLK_RD_ERR), strerror(errno));
|
||||
snprintf(g->Message, sizeof(g->Message), MSG(OPTBLK_RD_ERR), strerror(errno));
|
||||
goto err;
|
||||
} // endif size
|
||||
|
||||
@@ -1127,19 +1127,19 @@ bool TDBDOS::GetBlockValues(PGLOBAL g)
|
||||
|
||||
// Now start the reading process.
|
||||
if (fread(n, sizeof(int), NZ, opfile) != NZ) {
|
||||
sprintf(g->Message, MSG(OPT_HEAD_RD_ERR), strerror(errno));
|
||||
snprintf(g->Message, sizeof(g->Message), MSG(OPT_HEAD_RD_ERR), strerror(errno));
|
||||
goto err;
|
||||
} // endif size
|
||||
|
||||
if (n[0] == -i) {
|
||||
// Read the XDB2 opt values from the opt file
|
||||
if (n[1] != lg || n[2] != nrec || n[3] != block) {
|
||||
sprintf(g->Message, MSG(OPT_NOT_MATCH), filename);
|
||||
snprintf(g->Message, sizeof(g->Message), MSG(OPT_NOT_MATCH), filename);
|
||||
goto err;
|
||||
} // endif
|
||||
|
||||
if (fread(n, sizeof(int), 2, opfile) != 2) {
|
||||
sprintf(g->Message, MSG(OPT_HEAD_RD_ERR), strerror(errno));
|
||||
snprintf(g->Message, sizeof(g->Message), MSG(OPT_HEAD_RD_ERR), strerror(errno));
|
||||
goto err;
|
||||
} // endif fread
|
||||
|
||||
@@ -1151,7 +1151,7 @@ bool TDBDOS::GetBlockValues(PGLOBAL g)
|
||||
cdp->SetNdv((int)ndv);
|
||||
|
||||
if (fread(cdp->GetDval(), lg, ndv, opfile) != ndv) {
|
||||
sprintf(g->Message, MSG(OPT_DVAL_RD_ERR), strerror(errno));
|
||||
snprintf(g->Message, sizeof(g->Message), MSG(OPT_DVAL_RD_ERR), strerror(errno));
|
||||
goto err;
|
||||
} // endif size
|
||||
|
||||
@@ -1161,7 +1161,7 @@ bool TDBDOS::GetBlockValues(PGLOBAL g)
|
||||
cdp->SetNbm((int)nbm);
|
||||
|
||||
if (fread(cdp->GetBmap(), sizeof(int), nbk, opfile) != nbk) {
|
||||
sprintf(g->Message, MSG(OPT_BMAP_RD_ERR), strerror(errno));
|
||||
snprintf(g->Message, sizeof(g->Message), MSG(OPT_BMAP_RD_ERR), strerror(errno));
|
||||
goto err;
|
||||
} // endif size
|
||||
|
||||
@@ -1169,7 +1169,7 @@ bool TDBDOS::GetBlockValues(PGLOBAL g)
|
||||
} else {
|
||||
// Read the Min/Max values from the opt file
|
||||
if (n[0] != i || n[1] != lg || n[2] != nrec || n[3] != block) {
|
||||
sprintf(g->Message, MSG(OPT_NOT_MATCH), filename);
|
||||
snprintf(g->Message, sizeof(g->Message), MSG(OPT_NOT_MATCH), filename);
|
||||
goto err;
|
||||
} // endif
|
||||
|
||||
@@ -1177,7 +1177,7 @@ bool TDBDOS::GetBlockValues(PGLOBAL g)
|
||||
cdp->SetMin(PlugSubAlloc(g, NULL, blk * lg));
|
||||
|
||||
if (fread(cdp->GetMin(), lg, blk, opfile) != blk) {
|
||||
sprintf(g->Message, MSG(OPT_MIN_RD_ERR), strerror(errno));
|
||||
snprintf(g->Message, sizeof(g->Message), MSG(OPT_MIN_RD_ERR), strerror(errno));
|
||||
goto err;
|
||||
} // endif size
|
||||
|
||||
@@ -1185,7 +1185,7 @@ bool TDBDOS::GetBlockValues(PGLOBAL g)
|
||||
cdp->SetMax(PlugSubAlloc(g, NULL, blk * lg));
|
||||
|
||||
if (fread(cdp->GetMax(), lg, blk, opfile) != blk) {
|
||||
sprintf(g->Message, MSG(OPT_MAX_RD_ERR), strerror(errno));
|
||||
snprintf(g->Message, sizeof(g->Message), MSG(OPT_MAX_RD_ERR), strerror(errno));
|
||||
goto err;
|
||||
} // endif size
|
||||
|
||||
@@ -1488,7 +1488,7 @@ PBF TDBDOS::CheckBlockFilari(PGLOBAL g, PXOB *arg, int op, bool *cnv)
|
||||
if (conv) {
|
||||
// The constant has not the good type and will not match
|
||||
// the block min/max values. Warn and abort.
|
||||
sprintf(g->Message, "Block opt: %s", MSG(VALTYPE_NOMATCH));
|
||||
snprintf(g->Message, sizeof(g->Message), "Block opt: %s", MSG(VALTYPE_NOMATCH));
|
||||
PushWarning(g, this);
|
||||
return NULL;
|
||||
} // endif Conv
|
||||
@@ -1693,7 +1693,7 @@ int TDBDOS::MakeIndex(PGLOBAL g, PIXDEF pxdf, bool add)
|
||||
if (add && dfp->GetIndx()) {
|
||||
for (sxp = dfp->GetIndx(); sxp; sxp = sxp->GetNext())
|
||||
if (!stricmp(sxp->GetName(), pxdf->GetName())) {
|
||||
sprintf(g->Message, MSG(INDEX_YET_ON), pxdf->GetName(), Name);
|
||||
snprintf(g->Message, sizeof(g->Message), MSG(INDEX_YET_ON), pxdf->GetName(), Name);
|
||||
return RC_FX;
|
||||
} else if (!sxp->GetNext())
|
||||
break;
|
||||
@@ -1714,10 +1714,10 @@ int TDBDOS::MakeIndex(PGLOBAL g, PIXDEF pxdf, bool add)
|
||||
for (n = 0, xdp = pxdf; xdp; xdp = xdp->GetNext())
|
||||
for (kdp = xdp->GetToKeyParts(); kdp; kdp = kdp->GetNext()) {
|
||||
if (!(colp = ColDB(g, kdp->GetName(), 0))) {
|
||||
sprintf(g->Message, MSG(INDX_COL_NOTIN), kdp->GetName(), Name);
|
||||
snprintf(g->Message, sizeof(g->Message), MSG(INDX_COL_NOTIN), kdp->GetName(), Name);
|
||||
goto err;
|
||||
} else if (colp->GetResultType() == TYPE_DECIM) {
|
||||
sprintf(g->Message, "Decimal columns are not indexable yet");
|
||||
snprintf(g->Message, sizeof(g->Message), "Decimal columns are not indexable yet");
|
||||
goto err;
|
||||
} // endif Type
|
||||
|
||||
@@ -1845,14 +1845,14 @@ bool TDBDOS::InitialyzeIndex(PGLOBAL g, volatile PIXDEF xdp, bool sorted)
|
||||
// Get the key column description list
|
||||
for (k = 0, kdp = xdp->GetToKeyParts(); kdp; kdp = kdp->GetNext())
|
||||
if (!(colp = ColDB(g, kdp->GetName(), 0)) || colp->InitValue(g)) {
|
||||
sprintf(g->Message, "Wrong column %s", kdp->GetName());
|
||||
snprintf(g->Message, sizeof(g->Message), "Wrong column %s", kdp->GetName());
|
||||
return true;
|
||||
} else
|
||||
To_Key_Col[k++] = colp;
|
||||
|
||||
#if defined(_DEBUG)
|
||||
if (k != Knum) {
|
||||
sprintf(g->Message, "Key part number mismatch for %s",
|
||||
snprintf(g->Message, sizeof(g->Message), "Key part number mismatch for %s",
|
||||
xdp->GetName());
|
||||
return 0;
|
||||
} // endif k
|
||||
@@ -1953,7 +1953,7 @@ int TDBDOS::RowNumber(PGLOBAL g, bool)
|
||||
/*******************************************************************/
|
||||
/* Don't know how to retrieve RowID from file address. */
|
||||
/*******************************************************************/
|
||||
sprintf(g->Message, MSG(NO_ROWID_FOR_AM),
|
||||
snprintf(g->Message, sizeof(g->Message), MSG(NO_ROWID_FOR_AM),
|
||||
GetAmName(g, Txfp->GetAmType()));
|
||||
return 0;
|
||||
} else
|
||||
@@ -2479,7 +2479,7 @@ bool DOSCOL::VarSize(void)
|
||||
bool DOSCOL::SetBuffer(PGLOBAL g, PVAL value, bool ok, bool check)
|
||||
{
|
||||
if (!(To_Val = value)) {
|
||||
sprintf(g->Message, MSG(VALUE_ERROR), Name);
|
||||
snprintf(g->Message, sizeof(g->Message), MSG(VALUE_ERROR), Name);
|
||||
return true;
|
||||
} else if (Buf_Type == value->GetType()) {
|
||||
// Values are of the (good) column type
|
||||
@@ -2498,7 +2498,7 @@ bool DOSCOL::SetBuffer(PGLOBAL g, PVAL value, bool ok, bool check)
|
||||
} else {
|
||||
// Values are not of the (good) column type
|
||||
if (check) {
|
||||
sprintf(g->Message, MSG(TYPE_VALUE_ERR), Name,
|
||||
snprintf(g->Message, sizeof(g->Message), MSG(TYPE_VALUE_ERR), Name,
|
||||
GetTypeName(Buf_Type), GetTypeName(value->GetType()));
|
||||
return true;
|
||||
} // endif check
|
||||
@@ -2550,7 +2550,7 @@ void DOSCOL::ReadColumn(PGLOBAL g)
|
||||
if (!tdbp->IsRead())
|
||||
if ((rc = tdbp->ReadBuffer(g)) != RC_OK) {
|
||||
if (rc == RC_EF)
|
||||
sprintf(g->Message, MSG(INV_DEF_READ), rc);
|
||||
snprintf(g->Message, sizeof(g->Message), MSG(INV_DEF_READ), rc);
|
||||
|
||||
throw 11;
|
||||
} // endif
|
||||
@@ -2615,12 +2615,12 @@ void DOSCOL::ReadColumn(PGLOBAL g)
|
||||
|
||||
break;
|
||||
default:
|
||||
sprintf(g->Message, MSG(BAD_RECFM), tdbp->Ftype);
|
||||
snprintf(g->Message, sizeof(g->Message), MSG(BAD_RECFM), tdbp->Ftype);
|
||||
throw 34;
|
||||
} // endswitch Ftype
|
||||
|
||||
if (err) {
|
||||
sprintf(g->Message, "Out of range value for column %s at row %d",
|
||||
snprintf(g->Message, sizeof(g->Message), "Out of range value for column %s at row %d",
|
||||
Name, tdbp->RowNumber(g));
|
||||
PushWarning(g, tdbp);
|
||||
} // endif err
|
||||
@@ -2730,7 +2730,7 @@ void DOSCOL::WriteColumn(PGLOBAL g)
|
||||
len = strlen(Buf);
|
||||
break;
|
||||
default:
|
||||
sprintf(g->Message, "Invalid field format for column %s", Name);
|
||||
snprintf(g->Message, sizeof(g->Message), "Invalid field format for column %s", Name);
|
||||
throw 31;
|
||||
} // endswitch BufType
|
||||
|
||||
@@ -2744,7 +2744,7 @@ void DOSCOL::WriteColumn(PGLOBAL g)
|
||||
if ((len = n) > field) {
|
||||
char *p = Value->GetCharString(Buf);
|
||||
|
||||
sprintf(g->Message, MSG(VALUE_TOO_LONG), p, Name, field);
|
||||
snprintf(g->Message, sizeof(g->Message), MSG(VALUE_TOO_LONG), p, Name, field);
|
||||
throw 31;
|
||||
} else if (Dsp)
|
||||
for (i = 0; i < len; i++)
|
||||
@@ -2772,7 +2772,7 @@ void DOSCOL::WriteColumn(PGLOBAL g)
|
||||
/* Updating to be done only during the second pass (Status=true) */
|
||||
/*******************************************************************/
|
||||
if (Value->GetBinValue(p, Long, Status)) {
|
||||
sprintf(g->Message, MSG(BIN_F_TOO_LONG),
|
||||
snprintf(g->Message, sizeof(g->Message), MSG(BIN_F_TOO_LONG),
|
||||
Name, Value->GetSize(), Long);
|
||||
throw 31;
|
||||
} // endif
|
||||
@@ -2832,11 +2832,11 @@ bool DOSCOL::SetBitMap(PGLOBAL g)
|
||||
if ((i = Dval->Find(Value)) < 0) {
|
||||
char buf[32];
|
||||
|
||||
sprintf(g->Message, MSG(DVAL_NOTIN_LIST),
|
||||
snprintf(g->Message, sizeof(g->Message), MSG(DVAL_NOTIN_LIST),
|
||||
Value->GetCharString(buf), Name);
|
||||
return true;
|
||||
} else if (i >= dup->Maxbmp) {
|
||||
sprintf(g->Message, MSG(OPT_LOGIC_ERR), i);
|
||||
snprintf(g->Message, sizeof(g->Message), MSG(OPT_LOGIC_ERR), i);
|
||||
return true;
|
||||
} else {
|
||||
m = i / MAXBMP;
|
||||
@@ -2859,7 +2859,7 @@ bool DOSCOL::CheckSorted(PGLOBAL g)
|
||||
// Verify whether this column is sorted all right
|
||||
if (OldVal->CompareValue(Value) > 0) {
|
||||
// Column is no more in ascending order
|
||||
sprintf(g->Message, MSG(COL_NOT_SORTED), Name, To_Tdb->GetName());
|
||||
snprintf(g->Message, sizeof(g->Message), MSG(COL_NOT_SORTED), Name, To_Tdb->GetName());
|
||||
Sorted = false;
|
||||
return true;
|
||||
} else
|
||||
@@ -2900,7 +2900,7 @@ bool DOSCOL::AddDistinctValue(PGLOBAL g)
|
||||
// Check whether we have room for an additional value
|
||||
if (Ndv == Freq) {
|
||||
// Too many values because of wrong Freq setting
|
||||
sprintf(g->Message, MSG(BAD_FREQ_SET), Name);
|
||||
snprintf(g->Message, sizeof(g->Message), MSG(BAD_FREQ_SET), Name);
|
||||
return true;
|
||||
} // endif Ndv
|
||||
|
||||
|
Reference in New Issue
Block a user