mirror of
https://github.com/openbsd/src.git
synced 2025-01-10 06:47:55 -08:00
quiz: handle line continuation in data files correctly, switch to getline(3)
Specifically, the following quiz.db line foo:\ bar was parsed into "foo:bar\n", which made it impossible to answer correctly. Bug reported and inital fix from Alex Karle, partially reworked by yours truly, further input from millert@
This commit is contained in:
parent
6e9d372769
commit
5a0076c3c8
@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: quiz.c,v 1.30 2018/08/24 11:14:49 mestre Exp $ */
|
/* $OpenBSD: quiz.c,v 1.31 2021/03/11 21:18:25 naddy Exp $ */
|
||||||
/* $NetBSD: quiz.c,v 1.9 1995/04/22 10:16:58 cgd Exp $ */
|
/* $NetBSD: quiz.c,v 1.9 1995/04/22 10:16:58 cgd Exp $ */
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
@ -48,7 +48,6 @@ static QE qlist;
|
|||||||
static int catone, cattwo, tflag;
|
static int catone, cattwo, tflag;
|
||||||
static u_int qsize;
|
static u_int qsize;
|
||||||
|
|
||||||
char *appdstr(char *, const char *, size_t);
|
|
||||||
void downcase(char *);
|
void downcase(char *);
|
||||||
void get_cats(char *, char *);
|
void get_cats(char *, char *);
|
||||||
void get_file(const char *);
|
void get_file(const char *);
|
||||||
@ -110,7 +109,8 @@ get_file(const char *file)
|
|||||||
{
|
{
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
QE *qp;
|
QE *qp;
|
||||||
size_t len;
|
ssize_t len;
|
||||||
|
size_t qlen, size;
|
||||||
char *lp;
|
char *lp;
|
||||||
|
|
||||||
if ((fp = fopen(file, "r")) == NULL)
|
if ((fp = fopen(file, "r")) == NULL)
|
||||||
@ -123,26 +123,36 @@ get_file(const char *file)
|
|||||||
*/
|
*/
|
||||||
qp = &qlist;
|
qp = &qlist;
|
||||||
qsize = 0;
|
qsize = 0;
|
||||||
while ((lp = fgetln(fp, &len)) != NULL) {
|
qlen = 0;
|
||||||
|
lp = NULL;
|
||||||
|
size = 0;
|
||||||
|
while ((len = getline(&lp, &size, fp)) != -1) {
|
||||||
if (lp[len - 1] == '\n')
|
if (lp[len - 1] == '\n')
|
||||||
--len;
|
lp[--len] = '\0';
|
||||||
if (qp->q_text && qp->q_text[0] != '\0' &&
|
if (qp->q_text)
|
||||||
qp->q_text[strlen(qp->q_text) - 1] == '\\')
|
qlen = strlen(qp->q_text);
|
||||||
qp->q_text = appdstr(qp->q_text, lp, len);
|
if (qlen > 0 && qp->q_text[qlen - 1] == '\\') {
|
||||||
else {
|
qp->q_text[--qlen] = '\0';
|
||||||
|
qlen += len;
|
||||||
|
qp->q_text = realloc(qp->q_text, qlen + 1);
|
||||||
|
if (qp->q_text == NULL)
|
||||||
|
errx(1, "realloc");
|
||||||
|
strlcat(qp->q_text, lp, qlen + 1);
|
||||||
|
} else {
|
||||||
if ((qp->q_next = malloc(sizeof(QE))) == NULL)
|
if ((qp->q_next = malloc(sizeof(QE))) == NULL)
|
||||||
errx(1, "malloc");
|
errx(1, "malloc");
|
||||||
qp = qp->q_next;
|
qp = qp->q_next;
|
||||||
if ((qp->q_text = malloc(len + 1)) == NULL)
|
qp->q_text = strdup(lp);
|
||||||
errx(1, "malloc");
|
if (qp->q_text == NULL)
|
||||||
/* lp may not be zero-terminated; cannot use strlcpy */
|
errx(1, "strdup");
|
||||||
strncpy(qp->q_text, lp, len);
|
|
||||||
qp->q_text[len] = '\0';
|
|
||||||
qp->q_asked = qp->q_answered = FALSE;
|
qp->q_asked = qp->q_answered = FALSE;
|
||||||
qp->q_next = NULL;
|
qp->q_next = NULL;
|
||||||
++qsize;
|
++qsize;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
free(lp);
|
||||||
|
if (ferror(fp))
|
||||||
|
err(1, "getline");
|
||||||
(void)fclose(fp);
|
(void)fclose(fp);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -318,32 +328,6 @@ next_cat(const char *s)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
char *
|
|
||||||
appdstr(char *s, const char *tp, size_t len)
|
|
||||||
{
|
|
||||||
char *mp;
|
|
||||||
const char *sp;
|
|
||||||
int ch;
|
|
||||||
char *m;
|
|
||||||
|
|
||||||
if ((m = malloc(strlen(s) + len + 1)) == NULL)
|
|
||||||
errx(1, "malloc");
|
|
||||||
for (mp = m, sp = s; (*mp++ = *sp++) != '\0'; )
|
|
||||||
;
|
|
||||||
--mp;
|
|
||||||
if (*(mp - 1) == '\\')
|
|
||||||
--mp;
|
|
||||||
|
|
||||||
while ((ch = *mp++ = *tp++) && ch != '\n')
|
|
||||||
;
|
|
||||||
if (*(mp - 2) == '\\')
|
|
||||||
mp--;
|
|
||||||
*mp = '\0';
|
|
||||||
|
|
||||||
free(s);
|
|
||||||
return (m);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
score(u_int r, u_int w, u_int g)
|
score(u_int r, u_int w, u_int g)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user