]> git.cameronkatri.com Git - bsdgames-darwin.git/blobdiff - tetris/scores.c
Better check data read from tetris.scores before use as array indices etc.
[bsdgames-darwin.git] / tetris / scores.c
index 6afb11159ae98b95ad959b5f691e4bdf7c9fb55d..d215261cf15624728d5bce937b1c65d4059d4087 100644 (file)
@@ -1,4 +1,4 @@
-/*     $NetBSD: scores.c,v 1.4 1997/10/14 01:14:20 lukem Exp $ */
+/*     $NetBSD: scores.c,v 1.14 2006/06/01 16:12:27 drochner Exp $     */
 
 /*-
  * Copyright (c) 1992, 1993
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *     This product includes software developed by the University of
- *     California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  *
  *
  * Major whacks since then.
  */
+#include <err.h>
 #include <errno.h>
 #include <fcntl.h>
 #include <pwd.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <sys/stat.h>
 #include <time.h>
 #include <termcap.h>
 #include <unistd.h>
@@ -76,11 +74,11 @@ static int nscores;
 static int gotscores;
 static struct highscore scores[NUMSPOTS];
 
-static int checkscores __P((struct highscore *, int));
-static int cmpscores __P((const void *, const void *));
-static void getscores __P((FILE **));
-static void printem __P((int, int, struct highscore *, int, const char *));
-static char *thisuser __P((void));
+static int checkscores(struct highscore *, int);
+static int cmpscores(const void *, const void *);
+static void getscores(FILE **);
+static void printem(int, int, struct highscore *, int, const char *);
+static char *thisuser(void);
 
 /*
  * Read the score file.  Can be called from savescore (before showscores)
@@ -96,7 +94,8 @@ getscores(fpp)
        FILE **fpp;
 {
        int sd, mint, lck;
-       char *mstr, *human;
+       mode_t mask;
+       const char *mstr, *human;
        FILE *sf;
 
        if (fpp != NULL) {
@@ -110,35 +109,33 @@ getscores(fpp)
                human = "reading";
                lck = LOCK_SH;
        }
+       setegid(egid);
+       mask = umask(S_IWOTH);
        sd = open(_PATH_SCOREFILE, mint, 0666);
+       (void)umask(mask);
        if (sd < 0) {
                if (fpp == NULL) {
                        nscores = 0;
+                       setegid(gid);
                        return;
                }
-               (void)fprintf(stderr, "tetris: cannot open %s for %s: %s\n",
-                   _PATH_SCOREFILE, human, strerror(errno));
-               exit(1);
+               err(1, "cannot open %s for %s", _PATH_SCOREFILE, human);
        }
        if ((sf = fdopen(sd, mstr)) == NULL) {
-               (void)fprintf(stderr, "tetris: cannot fdopen %s for %s: %s\n",
-                   _PATH_SCOREFILE, human, strerror(errno));
-               exit(1);
+               err(1, "cannot fdopen %s for %s", _PATH_SCOREFILE, human);
        }
+       setegid(gid);
 
        /*
         * Grab a lock.
         */
        if (flock(sd, lck))
-               (void)fprintf(stderr,
-                   "tetris: warning: score file %s cannot be locked: %s\n",
-                   _PATH_SCOREFILE, strerror(errno));
+               warn("warning: score file %s cannot be locked",
+                   _PATH_SCOREFILE);
 
        nscores = fread(scores, sizeof(scores[0]), MAXHISCORES, sf);
        if (ferror(sf)) {
-               (void)fprintf(stderr, "tetris: error reading %s: %s\n",
-                   _PATH_SCOREFILE, strerror(errno));
-               exit(1);
+               err(1, "error reading %s", _PATH_SCOREFILE);
        }
 
        if (fpp)
@@ -151,8 +148,8 @@ void
 savescore(level)
        int level;
 {
-       register struct highscore *sp;
-       register int i;
+       struct highscore *sp;
+       int i;
        int change;
        FILE *sf;
        const char *me;
@@ -201,10 +198,9 @@ savescore(level)
                 */
                nscores = checkscores(scores, nscores);
                rewind(sf);
-               if (fwrite(scores, sizeof(*sp), nscores, sf) != nscores ||
+               if (fwrite(scores, sizeof(*sp), nscores, sf) != (size_t)nscores ||
                    fflush(sf) == EOF)
-                       (void)fprintf(stderr,
-                           "tetris: error writing %s: %s -- %s\n",
+                       warnx("error writing %s: %s -- %s",
                            _PATH_SCOREFILE, strerror(errno),
                            "high scores may be damaged");
        }
@@ -218,9 +214,9 @@ savescore(level)
 static char *
 thisuser()
 {
-       register const char *p;
-       register struct passwd *pw;
-       register size_t l;
+       const char *p;
+       struct passwd *pw;
+       size_t l;
        static char u[sizeof(scores[0].hs_name)];
 
        if (u[0])
@@ -251,8 +247,8 @@ static int
 cmpscores(x, y)
        const void *x, *y;
 {
-       register const struct highscore *a, *b;
-       register long l;
+       const struct highscore *a, *b;
+       long l;
 
        a = x;
        b = y;
@@ -279,17 +275,17 @@ cmpscores(x, y)
  */
 static int
 checkscores(hs, num)
-       register struct highscore *hs;
+       struct highscore *hs;
        int num;
 {
-       register struct highscore *sp;
-       register int i, j, k, numnames;
+       struct highscore *sp;
+       int i, j, k, numnames;
        int levelfound[NLEVELS];
        struct peruser {
                char *name;
                int times;
        } count[NUMSPOTS];
-       register struct peruser *pu;
+       struct peruser *pu;
 
        /*
         * Sort so that highest totals come first.
@@ -338,7 +334,8 @@ checkscores(hs, num)
                                continue;
                        }
                }
-               levelfound[sp->hs_level] = 1;
+        if (sp->hs_level < NLEVELS && sp->hs_level >= 0)
+               levelfound[sp->hs_level] = 1;
                i++, sp++;
        }
        return (num > MAXHISCORES ? MAXHISCORES : num);
@@ -355,8 +352,8 @@ void
 showscores(level)
        int level;
 {
-       register struct highscore *sp;
-       register int i, n, c;
+       struct highscore *sp;
+       int i, n, c;
        const char *me;
        int levelfound[NLEVELS];
 
@@ -377,12 +374,14 @@ showscores(level)
        for (i = MINLEVEL; i < NLEVELS; i++)
                levelfound[i] = 0;
        for (i = 0, sp = scores; i < nscores; i++, sp++) {
-               if (levelfound[sp->hs_level])
-                       sp->hs_time = 0;
-               else {
-                       sp->hs_time = 1;
-                       levelfound[sp->hs_level] = 1;
-               }
+        if (sp->hs_level < NLEVELS && sp->hs_level >= 0) {
+               if (levelfound[sp->hs_level])
+                       sp->hs_time = 0;
+                   else {
+                           sp->hs_time = 1;
+                       levelfound[sp->hs_level] = 1;
+                   }
+        }
        }
 
        /*
@@ -407,11 +406,11 @@ showscores(level)
 static void
 printem(level, offset, hs, n, me)
        int level, offset;
-       register struct highscore *hs;
-       register int n;
+       struct highscore *hs;
+       int n;
        const char *me;
 {
-       register struct highscore *sp;
+       struct highscore *sp;
        int nrows, row, col, item, i, highlight;
        char buf[100];
 #define        TITLE "Rank  Score   Name     (points/level)"
@@ -435,10 +434,9 @@ printem(level, offset, hs, n, me)
                                (void)putchar('\n');
                                continue;
                        }
-                       (void)printf(item + offset < 10 ? "  " : " ");
                        sp = &hs[item];
-                       (void)sprintf(buf,
-                           "%d%c %6d  %-11s (%d on %d)",
+                       (void)snprintf(buf, sizeof(buf),
+                           "%3d%c %6d  %-11s (%6d on %d)",
                            item + offset, sp->hs_time ? '*' : ' ',
                            sp->hs_score * sp->hs_level,
                            sp->hs_name, sp->hs_score, sp->hs_level);