aboutsummaryrefslogtreecommitdiffstats
path: root/FICS/ratings.c
diff options
context:
space:
mode:
Diffstat (limited to 'FICS/ratings.c')
-rw-r--r--FICS/ratings.c106
1 files changed, 74 insertions, 32 deletions
diff --git a/FICS/ratings.c b/FICS/ratings.c
index 53ee33a..2f82e62 100644
--- a/FICS/ratings.c
+++ b/FICS/ratings.c
@@ -31,6 +31,12 @@
Markus Uhlin 24/11/27 Added sscanf() width spec and
fixed ignored retvals.
Markus Uhlin 24/11/28 Added null checks
+ Markus Uhlin 25/03/16 Fixed use of 32-bit 'time_t'.
+ Markus Uhlin 25/04/06 Fixed Clang Tidy warnings.
+ Markus Uhlin 25/07/28 Fixed missing return-value check
+ for a 'scanf'-like function.
+ Markus Uhlin 25/07/28 Restricted file permissions upon
+ creation.
*/
#include "stdinclude.h"
@@ -38,6 +44,9 @@
#include <err.h>
#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <stdint.h>
#include "command.h"
#include "comproc.h"
@@ -345,49 +354,52 @@ load_ratings(void)
return;
}
- for (int i = 0; i < MAXHIST; i++) {
- int ret, errno_save;
+ for (int i = 0; i < MAXHIST && !feof(fp) && !ferror(fp); i++) {
+ int ret;
sHist[i] = bHist[i] = wHist[i] = lHist[i] = 0;
- errno = 0;
ret = fscanf(fp, "%d %d %d %d", &sHist[i], &bHist[i], &wHist[i],
&lHist[i]);
- errno_save = errno;
if (ret != 4) {
- if (feof(fp) || ferror(fp))
- break;
- errno = errno_save;
- warn("%s: too few items assigned (iteration: %d)",
- __func__, i);
+ warnx("%s: %s: too few items assigned (iteration: %d)",
+ __func__, fname, i);
+ fclose(fp);
+ return;
}
}
+ if (ferror(fp)) {
+ warnx("%s: %s: the error indicator is set", __func__, fname);
+ fclose(fp);
+ return;
+ }
+
fclose(fp);
- if (Rs_count) {
- Ratings_S_StdDev = sqrt(Rs_S / Rs_count);
+ if (Rs_count != 0) {
+ Ratings_S_StdDev = sqrt(Rs_S / Rs_count); // NOLINT
Ratings_S_Average = (Rs_total / (double)Rs_count);
} else {
Ratings_S_StdDev = 0;
Ratings_S_Average = 0;
}
- if (Rb_count) {
- Ratings_B_StdDev = sqrt(Rb_S / Rb_count);
+ if (Rb_count != 0) {
+ Ratings_B_StdDev = sqrt(Rb_S / Rb_count); // NOLINT
Ratings_B_Average = (Rb_total / (double)Rb_count);
} else {
Ratings_B_StdDev = 0;
Ratings_B_Average = 0;
}
- if (Rw_count) {
- Ratings_W_StdDev = sqrt(Rw_S / Rw_count);
+ if (Rw_count != 0) {
+ Ratings_W_StdDev = sqrt(Rw_S / Rw_count); // NOLINT
Ratings_W_Average = (Rw_total / (double)Rw_count);
} else {
Ratings_W_StdDev = 0;
Ratings_W_Average = 0;
}
- if (Rl_count) {
- Ratings_L_StdDev = sqrt(Rl_S / Rl_count);
+ if (Rl_count != 0) {
+ Ratings_L_StdDev = sqrt(Rl_S / Rl_count); // NOLINT
Ratings_L_Average = (Rl_total / (double)Rl_count);
} else {
Ratings_L_StdDev = 0;
@@ -400,12 +412,20 @@ save_ratings(void)
{
FILE *fp;
char fname[MAX_FILENAME_SIZE] = { '\0' };
+ int fd;
snprintf(fname, sizeof fname, "%s/newratingsV%d_data", stats_dir,
STATS_VERSION);
- if ((fp = fopen(fname, "w")) == NULL) {
+ errno = 0;
+ fd = open(fname, O_WRONLY|O_CREAT, S_IWUSR|S_IRUSR);
+
+ if (fd < 0) {
+ warn("%s: can't write ratings data", __func__);
+ return;
+ } else if ((fp = fdopen(fd, "w")) == NULL) {
warn("%s: can't write ratings data", __func__);
+ close(fd);
return;
}
@@ -754,7 +774,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
@@ -769,15 +789,16 @@ current_sterr(double s, int t)
* ics.onenet.net, if not elsewhere.
*/
PUBLIC void
-rating_sterr_delta(int p1, int p2, int type, int gtime, int result,
+rating_sterr_delta(int p1, int p2, int type, time_t gtime, int result,
int *deltarating, double *newsterr)
{
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;
@@ -866,12 +887,12 @@ PUBLIC int
rating_update(int g)
{
double wSigma, bSigma;
- int gtime;
int inprogress = (g == parray[garray[g].black].game);
int wDelta, bDelta;
int wRes, bRes;
statistics *b_stats;
statistics *w_stats;
+ time_t gtime;
/*
* If this is adjudication of stored game - be quiet about
@@ -1300,6 +1321,18 @@ com_statistics(int p, param_list param)
return COM_OK;
}
+/*
+ * Return the difference of 'a - b'
+ */
+PUBLIC int
+int_diff(const char *fn, const int a, const int b)
+{
+ if ((b > 0 && a < INT_MIN + b) ||
+ (b < 0 && a > INT_MAX + b))
+ errx(1, "%s: integer overflow (%d - %d)", fn, a, b);
+ return (a - b);
+}
+
PUBLIC int
com_fixrank(int p, param_list param)
{
@@ -1547,7 +1580,8 @@ GetRank(FILE *fp, char *target, int countComp)
char line[MAX_RANK_LINE] = { '\0' };
char login[MAX_LOGIN_NAME] = { '\0' };
int count = 0;
- int nGames, is_computer;
+ int is_computer = 0;
+ int nGames = 0;
int playerFound = 0;
while (fgets(line, sizeof line, fp) != NULL &&
@@ -1555,8 +1589,7 @@ GetRank(FILE *fp, char *target, int countComp)
_Static_assert(ARRAY_SIZE(login) > 19, "'login' too small");
if (sscanf(line, "%19s %*d %d %d", login, &nGames, &is_computer)
- != 1) {
-// warnx("%s: sscanf() error", __func__);
+ < 3) {
continue;
}
@@ -1579,16 +1612,20 @@ PositionFilePtr(FILE *fp, int count, int *last, int *nTied, int showComp)
return;
rating = nGames = is_computer = 0;
+ errno = 0;
rewind(fp);
+ if (errno) {
+ warn("%s: rewind", __func__);
+ return;
+ }
for (int i = 1; i < count; i++) {
do {
_Static_assert(ARRAY_SIZE(login) > 19,
"'login' too small");
- if (fgets(line, sizeof line, fp) == NULL ||
- feof(fp) ||
- ferror(fp))
+ if (feof(fp) || ferror(fp) ||
+ fgets(line, sizeof line, fp) == NULL)
break;
else if (sscanf(line, "%19s %d %d %d", login, &rating,
&nGames, &is_computer) != 4) {
@@ -1597,6 +1634,11 @@ PositionFilePtr(FILE *fp, int count, int *last, int *nTied, int showComp)
}
} while (!CountRankLine(showComp, login, nGames, is_computer));
+ if (ferror(fp)) {
+ warnx("%s: the error indicator is set", __func__);
+ return;
+ }
+
if (rating != *last) {
*nTied = 1;
*last = rating;
@@ -1615,7 +1657,7 @@ ShowRankEntry(int p, FILE *fp, int count, int comp, char *target,
// XXX
rating = 0;
- findable = (count > 0 && !feof(fp));
+ findable = (count > 0 && !feof(fp) && !ferror(fp));
nGames = 0;
is_comp = 0;
@@ -1812,9 +1854,9 @@ DisplayTargetRank(int p, char *target, int show, int showComp)
numAbove = CountAbove(numToShow, blitzRank, stdRank, wildRank, show);
- blitzCount = (blitzRank - numAbove);
- stdCount = (stdRank - numAbove);
- wildCount = (wildRank - numAbove);
+ blitzCount = int_diff(__func__, blitzRank, numAbove);
+ stdCount = int_diff(__func__, stdRank, numAbove);
+ wildCount = int_diff(__func__, wildRank, numAbove);
ShowRankLines(p, fb, fs, fw, blitzCount, stdCount, wildCount, numToShow,
showComp, show, target);