diff options
Diffstat (limited to 'FICS/ratings.c')
-rw-r--r-- | FICS/ratings.c | 106 |
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); |