bump
Omar Polo <[email protected]> wrote:
> Ben Fuller <[email protected]> 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 *