Ben Fuller <ben@bvnf.space> wrote:
> Did anyone have a look at this? Feedback is appreciated.
> 
> On Sun, Jul 03, 2022 at 02:31:42 +0100, Ben Fuller wrote:
> > One of the fgetln(3)s was previously converted to getline(3), but not
> > the other.
> > 
> > diff --git games/quiz/quiz.c games/quiz/quiz.c
> > index d4fd0604e0d..362fb1e24a8 100644
> > --- games/quiz/quiz.c
> > +++ games/quiz/quiz.c
> > @@ -224,7 +224,8 @@ quiz(void)
> >  {
> >     QE *qp;
> >     int i;
> > -   size_t len;
> > +   size_t size;
> > +   ssize_t len;
> >     u_int guesses, rights, wrongs;
> >     int next;
> >     char *answer, *t, question[LINE_SZ];
> > @@ -275,12 +276,15 @@ quiz(void)
> >                     qp->q_answered = TRUE;
> >                     continue;
> >             }
> > +           size = 0;
> > +           answer = NULL;

here you're leaking memory.

This whole block is in a loop so you're possibly overriding the memory
allocated in a previous cycle.  size and answer should be initialized
outside of the loop.

otherwise the diff reads fine to me and game works fine.

> >             qp->q_asked = TRUE;
> >             (void)printf("%s?\n", question);
> >             for (;; ++guesses) {
> > -                   if ((answer = fgetln(stdin, &len)) == NULL ||
> > +                   if ((len = getline(&answer, &size, stdin)) == -1 ||
> >                         answer[len - 1] != '\n') {
> >                             score(rights, wrongs, guesses);
> > +                           free(answer);
> >                             exit(0);
> > [...]

however, while limiting ourselves to replace fgetln with getline in
quiz(6) only?  other games could take advantage of that :)

(i couldn't help myself not to tweak save_file_name in battlestar too)

briefly (play)tested the affected games, everything seems fine.

ok?

diff /usr/src
commit - faf550173e173cd2ef8642601dc48202a09fd44f
path + /usr/src
blob - f7b08498dfdda4b4021212344862399e3c71728b
file + games/battlestar/cypher.c
--- games/battlestar/cypher.c
+++ games/battlestar/cypher.c
@@ -84,8 +84,9 @@ cypher(void)
        int     n;
        int     junk;
        int     lflag = -1;
-       char   *filename, *rfilename;
-       size_t  filename_len;
+       char   *line = NULL, *filename;
+       size_t  linesize = 0;
+       ssize_t linelen;
 
        while (wordnumber <= wordcount) {
                if (wordtype[wordnumber] != VERB &&
@@ -357,19 +358,16 @@ cypher(void)
                case SAVE:
                        printf("\nSave file name (default %s):  ",
                            DEFAULT_SAVE_FILE);
-                       filename = fgetln(stdin, &filename_len);
-                       if (filename_len == 0
-                           || (filename_len == 1 && filename[0] == '\n'))
-                               rfilename = save_file_name(DEFAULT_SAVE_FILE,
-                                   strlen(DEFAULT_SAVE_FILE));
+                       linelen = getline(&line, &linesize, stdin);
+                       if (linelen <= 1)
+                               filename = save_file_name(DEFAULT_SAVE_FILE);
                        else {
-                               if (filename[filename_len - 1] == '\n')
-                                       filename_len--;
-                               rfilename = save_file_name(filename,
-                                   filename_len);
+                               if (line[linelen - 1] == '\n')
+                                       line[linelen - 1] = '\0';
+                               filename = save_file_name(line);
                        }
-                       save(rfilename);
-                       free(rfilename);
+                       save(filename);
+                       free(filename);
                        break;
 
                case VERBOSE:
@@ -463,6 +461,9 @@ cypher(void)
                }
                if (!lflag)
                        newlocation();
+
+               free(line);
+
                if (wordnumber < wordcount && !stop_cypher &&
                    (*words[wordnumber] == ',' || *words[wordnumber] == '.')) {
                        wordnumber++;
blob - 21f8dc722600d3e169260e6e885319864c856807
file + games/battlestar/extern.h
--- games/battlestar/extern.h
+++ games/battlestar/extern.h
@@ -357,7 +357,7 @@ void ravage(void);
 void restore(const char *);
 int ride(void);
 void save(const char *);
-char *save_file_name(const char *, size_t);
+char *save_file_name(const char *);
 int shoot(void);
 int take(unsigned int[]);
 int takeoff(void);
blob - 5c2044a918e667bc505d35a2f27718d4dad0ba4a
file + games/battlestar/init.c
--- games/battlestar/init.c
+++ games/battlestar/init.c
@@ -66,7 +66,7 @@ initialize(const char *filename)
                for (p = dayobjs; p->room != 0; p++)
                        SetBit(location[p->room].objects, p->obj);
        } else {
-               savefile = save_file_name(filename, strlen(filename));
+               savefile = save_file_name(filename);
                restore(savefile);
                free(savefile);
        }
blob - 088bb2d2c5cb0f0cfff6485110646301c1665845
file + games/battlestar/save.c
--- games/battlestar/save.c
+++ games/battlestar/save.c
@@ -145,44 +145,26 @@ save(const char *filename)
 }
 
 /*
- * Given a save file name (possibly from fgetln, so without terminating NUL),
- * determine the name of the file to be saved to by adding the HOME
- * directory if the name does not contain a slash.  Name will be allocated
- * with malloc(3).
+ * Given a save file name determine the name of the file to be saved
+ * to by adding the HOME directory if the name does not contain a
+ * slash.  Name will be allocated with malloc(3).
  */
 char *
-save_file_name(const char *filename, size_t len)
+save_file_name(const char *filename)
 {
        char   *home;
        char   *newname;
-       size_t  tmpl;
 
-       if (memchr(filename, '/', len)) {
-               if ((newname = malloc(len + 1)) == NULL) {
+       home = getenv("HOME");
+       if (strchr(filename, '/') != NULL || home == NULL) {
+               if ((newname = strdup(filename)) == NULL)
                        warnx("out of memory");
-                       return NULL;
-               }
-               memcpy(newname, filename, len);
-               newname[len] = 0;
-       } else {
-               if ((home = getenv("HOME")) != NULL) {
-                       tmpl = strlen(home);
-                       if ((newname = malloc(tmpl + len + 2)) == NULL) {
-                               warnx("out of memory");
-                               return NULL;
-                       }
-                       memcpy(newname, home, tmpl);
-                       newname[tmpl] = '/';
-                       memcpy(newname + tmpl + 1, filename, len);
-                       newname[tmpl + len + 1] = 0;
-               } else {
-                       if ((newname = malloc(len + 1)) == NULL) {
-                               warnx("out of memory");
-                               return NULL;
-                       }
-                       memcpy(newname, filename, len);
-                       newname[len] = 0;
-               }
+               return(newname);
        }
+
+       if (asprintf(&newname, "%s/%s", home, filename) == -1) {
+               warnx("out of memory");
+               return NULL;
+       }
        return(newname);
 }
blob - 8c36bb1f110f2a2e0150e791e0917e8800c19483
file + games/hunt/huntd/conf.c
--- games/hunt/huntd/conf.c
+++ games/hunt/huntd/conf.c
@@ -247,24 +247,19 @@ parse_line(char *buf, char *fnm, int *line)
 static void
 load_config(FILE *f, char *fnm)
 {
-       char buf[BUFSIZ];
-       size_t len;
-       int line;
-       char *p;
+       int lineno;
+       char *line = NULL;
+       size_t linesize = 0;
+       ssize_t linelen;
 
-       line = 0;
-       while ((p = fgetln(f, &len)) != NULL) {
-               line++;
-               if (p[len-1] == '\n')
-                       len--;
-               if (len >= sizeof(buf)) {
-                       logx(LOG_ERR, "%s:%d: line too long", fnm, line);
-                       continue;
-               }
-               (void)memcpy(buf, p, len);
-               buf[len] = '\0';
-               parse_line(buf, fnm, &line);
+       lineno = 0;
+       while ((linelen = getline(&line, &linesize, stdin)) != -1) {
+               lineno++;
+               if (linelen > 1 && line[linelen - 1] == '\n')
+                       line[linelen - 1] = '\0';
+               parse_line(line, fnm, &lineno);
        }
+       free(line);
 }
 
 /*
blob - e8804e1a23d8d5c5e639f8ea59a09592097bf344
file + games/monop/execute.c
--- games/monop/execute.c
+++ games/monop/execute.c
@@ -285,7 +285,8 @@ rest_f(char *file)
        int  i, j, num;
        FILE *inf;
        char *st, *a, *b;
-       size_t len;
+       size_t linesize;
+       ssize_t len;
        STAT sbuf;
        int  t1;
        short t2, t3, t4;
@@ -302,19 +303,22 @@ rest_f(char *file)
        }
 
        num = 1;
-       st = fgetln(inf, &len);
-       if (st == NULL || len != strlen(MONOP_TAG) + 1 ||
+       st = NULL;
+       linesize = 0;
+       len = getline(&st, &linesize, inf);
+       if (len == -1 || len != strlen(MONOP_TAG) + 1 ||
            strncmp(st, MONOP_TAG, strlen(MONOP_TAG))) {
 badness:
                warnx("%s line %d", file, num);
+               free(st);
                fclose(inf);
                return(FALSE);
        }
        num++;
-       if (fgetln(inf, &len) == NULL)
+       if ((len = getline(&st, &linesize, inf)) == -1)
                goto badness;
        num++;
-       if ((st = fgetln(inf, &len)) == NULL || st[len - 1] != '\n')
+       if ((len = getline(&st, &linesize, inf)) == -1 || st[len - 1] != '\n')
                goto badness;
        st[len - 1] = '\0';
        if (sscanf(st, "%d %d %d", &num_play, &player, &num_doub) != 3 ||
@@ -328,7 +332,8 @@ badness:
        /* Names */
        for (i = 0; i < num_play; i++) {
                num++;
-               if ((st = fgetln(inf, &len)) == NULL || st[len - 1] != '\n')
+               if ((len = getline(&st, &linesize, inf)) == -1 ||
+                   st[len - 1] != '\n')
                        goto badness;
                st[len - 1] = '\0';
                if ((name_list[i] = play[i].name = strdup(st)) == NULL)
@@ -340,7 +345,8 @@ badness:
        /* Money, location, GOJF cards, turns in jail */
        for (i = 0; i < num_play; i++) {
                num++;
-               if ((st = fgetln(inf, &len)) == NULL || st[len - 1] != '\n')
+               if ((len = getline(&st, &linesize, inf)) == -1 ||
+                   st[len - 1] != '\n')
                        goto badness;
                st[len - 1] = '\0';
                if (sscanf(st, "%d %hd %hd %hd", &(play[i].money), &t2,
@@ -355,7 +361,8 @@ badness:
        /* Deck status; init_decks() must have been called. */
        for (i = 0; i < 2; i++) {
                num++;
-               if ((st = fgetln(inf, &len)) == NULL || st[len - 1] != '\n')
+               if ((len = getline(&st, &linesize, inf)) == -1 ||
+                   st[len - 1] != '\n')
                        goto badness;
                st[len - 1] = '\0';
                if (sscanf(st, "%d %d %hd", &t1, &j, &t2) != 3 ||
@@ -365,7 +372,8 @@ badness:
                deck[i].top_card = j;
                deck[i].gojf_used = t2;
                num++;
-               if ((st = fgetln(inf, &len)) == NULL || st[len - 1] != '\n')
+               if ((len = getline(&st, &linesize, inf)) == -1 ||
+                   st[len - 1] != '\n')
                        goto badness;
                st[len - 1] = '\0';
                a = st;
@@ -379,7 +387,7 @@ badness:
                /* Ignore anything trailing */
        }
        trading = FALSE;
-       while ((st = fgetln(inf, &len)) != NULL) {
+       while ((len = getline(&st, &linesize, inf)) != -1) {
                num++;
                if (st[len - 1] != '\n')
                        goto badness;
@@ -403,6 +411,7 @@ badness:
                 * within 1 in each monopoly
                 */
        }
+       free(st);
        fclose(inf);
        /* Check total hotel and house count */
        t1 = j = 0;
blob - d4fd0604e0de22cc4fe3f9e82940e4a449589413
file + games/quiz/quiz.c
--- games/quiz/quiz.c
+++ games/quiz/quiz.c
@@ -224,12 +224,16 @@ quiz(void)
 {
        QE *qp;
        int i;
-       size_t len;
+       size_t size;
+       ssize_t len;
        u_int guesses, rights, wrongs;
        int next;
        char *answer, *t, question[LINE_SZ];
        const char *s;
 
+       size = 0;
+       answer = NULL;
+
        guesses = rights = wrongs = 0;
        for (;;) {
                if (qsize == 0)
@@ -278,9 +282,10 @@ quiz(void)
                qp->q_asked = TRUE;
                (void)printf("%s?\n", question);
                for (;; ++guesses) {
-                       if ((answer = fgetln(stdin, &len)) == NULL ||
+                       if ((len = getline(&answer, &size, stdin)) == -1 ||
                            answer[len - 1] != '\n') {
                                score(rights, wrongs, guesses);
+                               free(answer);
                                exit(0);
                        }
                        answer[len - 1] = '\0';
@@ -302,6 +307,7 @@ quiz(void)
                }
        }
        score(rights, wrongs, guesses);
+       free(answer);
 }
 
 const char *

Reply via email to