bump Omar Polo <o...@openbsd.org> wrote: > Ben Fuller <ben@bvnf.space> wrote: > > 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?
Index: battlestar/cypher.c =================================================================== RCS file: /home/cvs/src/games/battlestar/cypher.c,v retrieving revision 1.20 diff -u -p -r1.20 cypher.c --- battlestar/cypher.c 9 May 2019 20:19:22 -0000 1.20 +++ battlestar/cypher.c 8 Aug 2022 07:05:43 -0000 @@ -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 || *line == '\n') + 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++; Index: battlestar/extern.h =================================================================== RCS file: /home/cvs/src/games/battlestar/extern.h,v retrieving revision 1.22 diff -u -p -r1.22 extern.h --- battlestar/extern.h 5 Feb 2022 23:00:20 -0000 1.22 +++ battlestar/extern.h 8 Aug 2022 07:05:43 -0000 @@ -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); Index: battlestar/init.c =================================================================== RCS file: /home/cvs/src/games/battlestar/init.c,v retrieving revision 1.17 diff -u -p -r1.17 init.c --- battlestar/init.c 9 May 2019 20:19:23 -0000 1.17 +++ battlestar/init.c 8 Aug 2022 07:05:43 -0000 @@ -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); } Index: battlestar/save.c =================================================================== RCS file: /home/cvs/src/games/battlestar/save.c,v retrieving revision 1.13 diff -u -p -r1.13 save.c --- battlestar/save.c 31 Dec 2015 17:51:19 -0000 1.13 +++ battlestar/save.c 8 Aug 2022 07:05:43 -0000 @@ -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); } Index: hunt/huntd/conf.c =================================================================== RCS file: /home/cvs/src/games/hunt/huntd/conf.c,v retrieving revision 1.13 diff -u -p -r1.13 conf.c --- hunt/huntd/conf.c 21 Jan 2017 08:22:57 -0000 1.13 +++ hunt/huntd/conf.c 8 Aug 2022 07:05:43 -0000 @@ -247,24 +247,18 @@ parse_line(char *buf, char *fnm, int *li static void load_config(FILE *f, char *fnm) { - char buf[BUFSIZ]; - size_t len; - int line; - char *p; + int lineno = 0; + 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); + while ((linelen = getline(&line, &linesize, stdin)) != -1) { + lineno++; + if (line[linelen - 1] == '\n') + line[linelen - 1] = '\0'; + parse_line(line, fnm, &lineno); } + free(line); } /* Index: monop/execute.c =================================================================== RCS file: /home/cvs/src/games/monop/execute.c,v retrieving revision 1.15 diff -u -p -r1.15 execute.c --- monop/execute.c 28 Jun 2019 13:32:52 -0000 1.15 +++ monop/execute.c 8 Aug 2022 07:05:43 -0000 @@ -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 (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; Index: quiz/quiz.c =================================================================== RCS file: /home/cvs/src/games/quiz/quiz.c,v retrieving revision 1.31 diff -u -p -r1.31 quiz.c --- quiz/quiz.c 11 Mar 2021 21:18:25 -0000 1.31 +++ quiz/quiz.c 8 Aug 2022 07:05:43 -0000 @@ -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 *