aboutsummaryrefslogtreecommitdiffstats
path: root/FICS/gamedb.c
diff options
context:
space:
mode:
Diffstat (limited to 'FICS/gamedb.c')
-rw-r--r--FICS/gamedb.c110
1 files changed, 74 insertions, 36 deletions
diff --git a/FICS/gamedb.c b/FICS/gamedb.c
index 572abf5..7f5e645 100644
--- a/FICS/gamedb.c
+++ b/FICS/gamedb.c
@@ -36,6 +36,15 @@
Markus Uhlin 24/11/25 Null checks
Markus Uhlin 24/12/02 Fixed bugs and ignored function
return values.
+ Markus Uhlin 25/03/18 Fixed unchecked return values
+ Markus Uhlin 25/03/25 ReadGameState: fixed truncated
+ stdio return value.
+ Markus Uhlin 25/04/01 Fixed call of risky function
+ Markus Uhlin 25/04/01 ReadV1GameFmt: guard num half
+ moves.
+ Markus Uhlin 25/04/06 Fixed Clang Tidy warnings.
+ Markus Uhlin 25/07/28 Fixed use of potentially
+ dangerous functions.
*/
#include "stdinclude.h"
@@ -43,6 +52,7 @@
#include <err.h>
#include <errno.h>
+#include <limits.h>
#include "command.h"
#include "config.h"
@@ -555,12 +565,12 @@ EndSym(int g)
PUBLIC char *
movesToString(int g, int pgn)
{
+ char tmp[160] = { '\0' };
char *serv_loc = SERVER_LOCATION;
char *serv_name = SERVER_NAME;
- char tmp[160] = { '\0' };
int i, col;
int wr, br;
- struct tm *tm_ptr = NULL;
+ struct tm v_tm = {0};
time_t curTime;
wr = garray[g].white_rating;
@@ -578,14 +588,16 @@ movesToString(int g, int pgn)
serv_name,
serv_loc);
- if ((tm_ptr = localtime(&curTime)) != NULL) {
+ errno = 0;
+
+ if (localtime_r(&curTime, &v_tm) != NULL) {
strftime(tmp, sizeof(tmp),
"[Date \"%Y.%m.%d\"]\n"
"[Time \"%H:%M:%S\"]\n",
- tm_ptr);
+ &v_tm);
mstrlcat(gameString, tmp, sizeof gameString);
} else
- warn("%s: localtime", __func__);
+ warn("%s: localtime_r()", __func__);
msnprintf(tmp, sizeof tmp,
"[Round \"-\"]\n"
@@ -660,11 +672,13 @@ movesToString(int g, int pgn)
mstrlcat(gameString, tmp, sizeof gameString);
mstrlcat(gameString, "--- ", sizeof gameString);
- if ((tm_ptr = localtime(&curTime)) != NULL) {
- strftime(tmp, sizeof tmp, "%Y.%m.%d %H:%M:%S", tm_ptr);
+ errno = 0;
+
+ if (localtime_r(&curTime, &v_tm) != NULL) {
+ strftime(tmp, sizeof tmp, "%Y.%m.%d %H:%M:%S", &v_tm);
mstrlcat(gameString, tmp, sizeof gameString);
} else
- warn("%s: localtime", __func__);
+ warn("%s: localtime_r()", __func__);
if (garray[g].rated) {
mstrlcat(gameString, "\nRated ", sizeof gameString);
@@ -974,8 +988,8 @@ WriteGameState(FILE *fp, game_state_t *gs)
PRIVATE int
ReadGameState(FILE *fp, game_state_t *gs, int version)
{
- char pieceChar;
int i, j;
+ int pieceChar;
int wkmoved, wqrmoved, wkrmoved, bkmoved, bqrmoved, bkrmoved;
if (version == 0) {
@@ -986,11 +1000,12 @@ ReadGameState(FILE *fp, game_state_t *gs, int version)
}
}
} else {
- getc(fp); /* Skip past a newline. */
+ (void) getc(fp); /* Skip past a newline. */
for (i = 0; i < 8; i++) {
for (j = 0; j < 8; j++) {
- pieceChar = getc(fp);
+ if ((pieceChar = getc(fp)) == EOF)
+ return -1;
gs->board[i][j] = CharToPiece(pieceChar);
}
}
@@ -1059,10 +1074,16 @@ got_attr_value(int g, char *attr, char *value, FILE *fp, char *file)
} else if (!strcmp(attr, "type:")) {
garray[g].type = atoi(value);
} else if (!strcmp(attr, "halfmoves:")) {
- garray[g].numHalfMoves = atoi(value);
-
- if (garray[g].numHalfMoves == 0)
+ if ((garray[g].numHalfMoves = atoi(value)) == 0)
return 0;
+ else if (garray[g].numHalfMoves < 0 ||
+ (size_t)garray[g].numHalfMoves > INT_MAX / sizeof(move_t)) {
+ warnx("%s: num half moves out-of-bounds (%d)", __func__,
+ garray[g].numHalfMoves);
+ return -1;
+ } else {
+ /* null */;
+ }
garray[g].moveListSize = garray[g].numHalfMoves;
garray[g].moveList = reallocarray(NULL, sizeof(move_t),
@@ -1267,8 +1288,10 @@ ReadV1GameFmt(game *g, FILE *fp, const char *file, int version)
_Static_assert(17 < ARRAY_SIZE(g->black_name), "Unexpected array size");
ret[0] = fscanf(fp, "%17s %17s", g->white_name, g->black_name);
- ret[1] = fscanf(fp, "%d %d", &g->white_rating, &g->black_rating);
- ret[2] = fscanf(fp, "%d %d %d %d",
+ ret[1] = fscanf(fp, "%d %d", // NOLINT
+ &g->white_rating,
+ &g->black_rating);
+ ret[2] = fscanf(fp, "%d %d %d %d", // NOLINT
&g->wInitTime,
&g->wIncrement,
&g->bInitTime,
@@ -1311,10 +1334,16 @@ ReadV1GameFmt(game *g, FILE *fp, const char *file, int version)
ret[0] = fscanf(fp, "%d %d %d %d", &g->private, &g->type, &g->rated,
&g->clockStopped);
- ret[1] = fscanf(fp, "%d", &g->numHalfMoves);
+ ret[1] = fscanf(fp, "%d", &g->numHalfMoves); // NOLINT
if (ret[0] != 4 || ret[1] != 1) {
warnx("%s: fscanf error: %s", __func__, file);
return -1;
+ } else if (g->numHalfMoves < 0 || (size_t)g->numHalfMoves >
+ INT_MAX / sizeof(move_t)) {
+ warnx("%s: warning: num half moves out-of-bounds (%d)",
+ __func__,
+ g->numHalfMoves);
+ return -1;
}
if (ReadV1Moves(g, fp) != 0) {
@@ -1625,10 +1654,9 @@ RemoveHistGame(char *file, int maxlines)
char Opponent[MAX_LOGIN_NAME + 1] = { '\0' };
char line[MAX_LINE_SIZE] = { '\0' };
int count = 0;
- long int When, oppWhen;
+ long int When = 0, oppWhen = 0;
_Static_assert(20 < ARRAY_SIZE(Opponent), "Not within bounds");
- When = oppWhen = 0;
if ((fp = fopen(file, "r")) == NULL) {
return;
@@ -1840,38 +1868,46 @@ write_g_out(int g, char *file, int maxlines, int isDraw, char *EndSymbol,
* Find from_spot in journal list - return 0 if corrupted
*/
PUBLIC int
-journal_get_info(int p, char from_spot, char *WhiteName, int *WhiteRating,
- char *BlackName, int *BlackRating, char *type, int *t, int *i, char *eco,
- char *ending, char *result, char *fname)
+journal_get_info(struct JGI_context *ctx, const char *fname)
{
FILE *fp;
char count;
if ((fp = fopen(fname, "r")) == NULL) {
fprintf(stderr, "Corrupt journal file! %s\n", fname);
- pprintf(p, "The journal file is corrupt! See an admin.\n");
+ pprintf(ctx->p, "The journal file is corrupt! See an admin.\n");
return 0;
}
while (!feof(fp)) {
- if (fscanf(fp, "%c %s %d %s %d %s %d %d %s %s %s\n",
+ _Static_assert(ARRAY_SIZE(ctx->WhiteName) > 20,
+ "'WhiteName' too small");
+ _Static_assert(ARRAY_SIZE(ctx->BlackName) > 20,
+ "'BlackName' too small");
+
+ _Static_assert(ARRAY_SIZE(ctx->type) > 99, "'type' too small");
+ _Static_assert(ARRAY_SIZE(ctx->eco) > 99, "'eco' too small");
+ _Static_assert(ARRAY_SIZE(ctx->ending) > 99, "'ending' too small");
+ _Static_assert(ARRAY_SIZE(ctx->result) > 99, "'result' too small");
+
+ if (fscanf(fp, "%c %20s %d %20s %d %99s %d %d %99s %99s %99s\n",
&count,
- WhiteName, &(*WhiteRating),
- BlackName, &(*BlackRating),
- type,
- &(*t), &(*i),
- eco,
- ending,
- result) != 11) {
+ ctx->WhiteName, &ctx->WhiteRating,
+ ctx->BlackName, &ctx->BlackRating,
+ ctx->type,
+ &ctx->t, &ctx->i,
+ ctx->eco,
+ ctx->ending,
+ ctx->result) != 11) {
fprintf(stderr, "FICS: Error in journal info format. "
"%s\n", fname);
- pprintf(p, "The journal file is corrupt! Error in "
+ pprintf(ctx->p, "The journal file is corrupt! Error in "
"internal format.\n");
fclose(fp);
return 0;
}
- if (tolower(count) == from_spot) {
+ if (tolower(count) == ctx->from_spot) {
fclose(fp);
return 1;
}
@@ -1922,7 +1958,7 @@ addjournalitem(int p, char count2, char *WhiteName2, int WhiteRating2,
ending2,
result2);
fclose(fp2);
- rename(fname2, fname);
+ xrename(__func__, fname2, fname);
return;
} else {
_Static_assert(ARRAY_SIZE(WhiteName) > 19,
@@ -1996,7 +2032,7 @@ addjournalitem(int p, char count2, char *WhiteName2, int WhiteRating2,
fclose(fp);
fclose(fp2);
- rename(fname2, fname);
+ xrename(__func__, fname2, fname);
}
PUBLIC int
@@ -2093,6 +2129,8 @@ pgames(int p, int p1, char *fname)
_Static_assert(ARRAY_SIZE(ending) > 99, "'ending' too small");
while (!feof(fp)) {
+ char tbuf[30] = { '\0' };
+
if (fscanf(fp, "%d %1s %d %1s %d %19s %99s %d %d %d %d %99s "
"%99s %ld\n",
&count, result, &MyRating, MyColor,
@@ -2115,7 +2153,7 @@ pgames(int p, int p1, char *fname)
count, result, MyRating, MyColor,
OppRating, OppName,
type, (wt / 600), (wi / 10), eco, ending,
- ctime(&t));
+ ctime_r(&t, tbuf) != NULL ? &tbuf[0] : "");
}
fclose(fp);