diff options
-rw-r--r-- | CHANGELOG.md | 5 | ||||
-rw-r--r-- | FICS/comproc.c | 20 | ||||
-rw-r--r-- | FICS/fics_addplayer.c | 7 | ||||
-rw-r--r-- | FICS/gamedb.c | 4 | ||||
-rw-r--r-- | FICS/makerank.c | 28 | ||||
-rw-r--r-- | FICS/obsproc.c | 23 | ||||
-rw-r--r-- | FICS/playerdb.c | 36 | ||||
-rw-r--r-- | FICS/ratings.c | 6 | ||||
-rw-r--r-- | README.md | 14 |
9 files changed, 114 insertions, 29 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 12535cf..2e330ac 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,8 @@ All notable changes to this fork of FICS version 1.6.2 will be documented in this file. ## [Unreleased] ## +- Changed the addplayer program to output a restart notice if an admin + account is created. - Changed the program to avoid calculating the same string multiple times. Multiple occurrences, found by PVS-Studio. - Fixed `-Wshadow` warnings. Multiple occurrences. @@ -12,7 +14,10 @@ documented in this file. - Fixed negative array index read in `accept_match()`. - Fixed null pointer dereferences. - Fixed out-of-bounds array access in `has_legal_move()`. +- Fixed overflowed array index read/write. Multiple occurrences. +- Fixed overflowed return value in `player_search()`. - Fixed possible buffer overflow in `FindHistory2()`. +- Fixed truncated stdio return value in `ReadGameState()`. - Fixed unchecked function return values. Multiple occurrences. - Fixed uninitialized variables. - Fixed untrusted array indices. diff --git a/FICS/comproc.c b/FICS/comproc.c index 4f33d4c..31f6064 100644 --- a/FICS/comproc.c +++ b/FICS/comproc.c @@ -41,6 +41,8 @@ value 'rat' in who_terse(). Markus Uhlin 25/03/16 Fixed use of 32-bit 'time_t'. Markus Uhlin 25/03/16 Fixed untrusted array index. + Markus Uhlin 25/03/25 com_unalias: fixed overflowed + array index read/write. */ #include "stdinclude.h" @@ -1639,14 +1641,32 @@ com_unalias(int p, param_list param) pprintf(p, "You have no alias named '%s'.\n", param[0].val.word); } else { + bool removed = false; + const int sz = (int) ARRAY_SIZE(parray[0].alias_list); + rfree(parray[p].alias_list[al].comm_name); rfree(parray[p].alias_list[al].alias); + parray[p].alias_list[al].comm_name = NULL; + parray[p].alias_list[al].alias = NULL; + for (int i = al; i < parray[p].numAlias; i++) { + if (i >= sz || i + 1 >= sz) { + warnx("%s: overflowed array index read/write", + __func__); + break; + } + parray[p].alias_list[i].comm_name = parray[p].alias_list[i + 1].comm_name; parray[p].alias_list[i].alias = parray[p].alias_list[i + 1].alias; + removed = true; + } + + if (!removed) { + pprintf(p, "Remove error.\n"); + return COM_FAILED; } parray[p].numAlias--; diff --git a/FICS/fics_addplayer.c b/FICS/fics_addplayer.c index 80be9fe..ad6c43f 100644 --- a/FICS/fics_addplayer.c +++ b/FICS/fics_addplayer.c @@ -27,6 +27,8 @@ Markus Uhlin 24/04/01 Fixed empty hostname Markus Uhlin 24/04/04 Added usage of explicit_bzero() Markus Uhlin 24/05/25 Added command-line option 'a' + Markus Uhlin 25/03/23 Output restart notice if the + player is admin. */ #include "stdinclude.h" @@ -157,6 +159,11 @@ main(int argc, char *argv[]) funame, fname, email, password); printf("Admin: %s\n", (parray[p].adminLevel > 0 ? "Yes" : "No")); + if (parray[p].adminLevel > 0) { + printf("Player is admin. Please restart FICS in order for " + "the changes to take effect.\n"); + } + snprintf(text, sizeof text, "\nYour player account has been created.\n\n" "Login Name: %s\n" diff --git a/FICS/gamedb.c b/FICS/gamedb.c index 6845c1d..a34fd89 100644 --- a/FICS/gamedb.c +++ b/FICS/gamedb.c @@ -37,6 +37,8 @@ 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. */ #include "stdinclude.h" @@ -975,8 +977,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) { diff --git a/FICS/makerank.c b/FICS/makerank.c index bdc4d3b..4458f31 100644 --- a/FICS/makerank.c +++ b/FICS/makerank.c @@ -110,21 +110,33 @@ GetPlayerInfo(char *fileName, ENTRY *e) "strlcpy() truncated\n", __func__); } } else if (!strcmp(field, "S_NUM:")) { - sscanf(line, "%*s %d", &(e->r[0].num)); + if (sscanf(line, "%*s %d", &(e->r[0].num)) != 1) + warnx("%s: S_NUM error", __func__); } else if (!strcmp(field, "B_NUM:")) { - sscanf(line, "%*s %d", &(e->r[1].num)); + if (sscanf(line, "%*s %d", &(e->r[1].num)) != 1) + warnx("%s: B_NUM error", __func__); } else if (!strcmp(field, "W_NUM:")) { - sscanf(line, "%*s %d", &(e->r[2].num)); + if (sscanf(line, "%*s %d", &(e->r[2].num)) != 1) + warnx("%s: W_NUM error", __func__); } else if (!strcmp(field, "L_NUM:")) { - sscanf(line, "%*s %d", &(e->r[3].num)); + if (sscanf(line, "%*s %d", &(e->r[3].num)) != 1) + warnx("%s: L_NUM error", __func__); } else if (!strcmp(field, "S_RATING:")) { - sscanf(line, "%*s %d", &(e->r[0].rating)); + if (sscanf(line, "%*s %d", + &(e->r[0].rating)) != 1) + warnx("%s: S_RATING error", __func__); } else if (!strcmp(field, "B_RATING:")) { - sscanf(line, "%*s %d", &(e->r[1].rating)); + if (sscanf(line, "%*s %d", + &(e->r[1].rating)) != 1) + warnx("%s: B_RATING error", __func__); } else if (!strcmp(field, "W_RATING:")) { - sscanf(line, "%*s %d", &(e->r[2].rating)); + if (sscanf(line, "%*s %d", + &(e->r[2].rating)) != 1) + warnx("%s: W_RATING error", __func__); } else if (!strcmp(field, "L_RATING:")) { - sscanf(line, "%*s %d", &(e->r[3].rating)); + if (sscanf(line, "%*s %d", + &(e->r[3].rating)) != 1) + warnx("%s: L_RATING error", __func__); } else if (!strcmp(field, "Network:")) { done = 1; } diff --git a/FICS/obsproc.c b/FICS/obsproc.c index 283ecc3..43954ff 100644 --- a/FICS/obsproc.c +++ b/FICS/obsproc.c @@ -90,19 +90,22 @@ GameNumFromParam(int p, int *p1, parameter *param) PRIVATE int gamesortfunc(const void *i, const void *j) { + const int x = *(int *)i; + const int y = *(int *)j; + /* * examine mode games moved to top of "games" output */ - return (GetRating(&parray[garray[*(int *)i].white], - garray[*(int *)i].type) + - GetRating(&parray[garray[*(int *)i].black], - garray[*(int *)i].type) - - (garray[*(int *)i].status == GAME_EXAMINE ? 10000 : 0) - - GetRating(&parray[garray[*(int *)j].white], - garray[*(int *)j].type) - - GetRating(&parray[garray[*(int *)j].black], - garray[*(int *)j].type) + - (garray[*(int *)j].status == GAME_EXAMINE ? 10000 : 0)); + return (GetRating(&parray[garray[x].white], + garray[x].type) + + GetRating(&parray[garray[x].black], + garray[x].type) - + (garray[x].status == GAME_EXAMINE ? 10000 : 0) - + GetRating(&parray[garray[y].white], + garray[y].type) - + GetRating(&parray[garray[y].black], + garray[y].type) + + (garray[y].status == GAME_EXAMINE ? 10000 : 0)); } PUBLIC int diff --git a/FICS/playerdb.c b/FICS/playerdb.c index cf7a014..cda4e1a 100644 --- a/FICS/playerdb.c +++ b/FICS/playerdb.c @@ -38,6 +38,8 @@ Markus Uhlin 25/02/11 Calc string length once Markus Uhlin 25/03/22 Fixed overflowed return value in player_search(). + Markus Uhlin 25/03/23 Fixed overflowed array index + read/write. */ #include "stdinclude.h" @@ -1788,17 +1790,26 @@ player_new_pendto(int p) PUBLIC int player_remove_pendto(int p, int p1, int type) { - int w; + bool removed = false; + int w; if ((w = player_find_pendto(p, p1, type)) < 0) return -1; - for (; w < (parray[p].num_to - 1); w++) + for (; w < (parray[p].num_to - 1); w++) { + if (w + 1 >= (int)ARRAY_SIZE(parray[0].p_to_list)) { + warnx("%s: overflowed array index write", __func__); + break; + } + parray[p].p_to_list[w] = parray[p].p_to_list[w + 1]; + removed = true; + } - parray[p].num_to = (parray[p].num_to - 1); + if (removed) + parray[p].num_to -= 1; - return 0; + return (removed ? 0 : -1); } PUBLIC int @@ -1842,17 +1853,26 @@ player_new_pendfrom(int p) PUBLIC int player_remove_pendfrom(int p, int p1, int type) { - int w; + bool removed = false; + int w; if ((w = player_find_pendfrom(p, p1, type)) < 0) return -1; - for (; w < (parray[p].num_from - 1); w++) + for (; w < (parray[p].num_from - 1); w++) { + if (w + 1 >= (int)ARRAY_SIZE(parray[0].p_from_list)) { + warnx("%s: overflowed array index write", __func__); + break; + } + parray[p].p_from_list[w] = parray[p].p_from_list[w + 1]; + removed = true; + } - parray[p].num_from = (parray[p].num_from - 1); + if (removed) + parray[p].num_from -= 1; - return 0; + return (removed ? 0 : -1); } PUBLIC int diff --git a/FICS/ratings.c b/FICS/ratings.c index b860260..3a7cdd0 100644 --- a/FICS/ratings.c +++ b/FICS/ratings.c @@ -39,6 +39,7 @@ #include <err.h> #include <errno.h> +#include <stdint.h> #include "command.h" #include "comproc.h" @@ -755,7 +756,7 @@ GE(int r, int rr, double ss, double *fss) } PRIVATE double -current_sterr(double s, int t) +current_sterr(double s, int64_t t) { if (t < 0) t = 0; // this shouldn't happen @@ -776,9 +777,10 @@ rating_sterr_delta(int p1, int p2, int type, time_t gtime, int result, double E, fs2, denominator, GK, w; // Parts of fancy formulas double delta, sigma; // Results to return double s1, s2; - int t1, r1, t2, r2; // Initial sterrs and ratings + int r1, r2; // Initial sterrs and ratings statistics *p1_stats; statistics *p2_stats; + time_t t1, t2; if (type == TYPE_BLITZ) { p1_stats = &parray[p1].b_stats; @@ -37,6 +37,16 @@ repository: $ git clone https://github.com/uhlin/fics.git $ cd fics +### Checkout ### + +If you want you can checkout a specific version. For example: + + $ git checkout 1.4.4 + +To see all tags, type: + + $ git tag + Edit `FICS/config.h` with a text editor and save the file. $ emacs FICS/config.h @@ -53,6 +63,10 @@ running `make install`. Done! +**NOTE**: +Running `make install` multiple times is totally fine and does no harm +when a new version of FICS is available. + ### Make variables ### If you want you can customize the `FICS_HOME` and `PREFIX` make |