aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md5
-rw-r--r--FICS/comproc.c20
-rw-r--r--FICS/fics_addplayer.c7
-rw-r--r--FICS/gamedb.c4
-rw-r--r--FICS/makerank.c28
-rw-r--r--FICS/obsproc.c23
-rw-r--r--FICS/playerdb.c36
-rw-r--r--FICS/ratings.c6
-rw-r--r--README.md14
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;
diff --git a/README.md b/README.md
index 4a92f79..ad34c47 100644
--- a/README.md
+++ b/README.md
@@ -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