From 31de6cad17ff8f82c8e0e4d247bf6428816b1148 Mon Sep 17 00:00:00 2001 From: "Jason A. Harmening" Date: Sun, 12 Apr 2020 02:42:42 +0000 Subject: [PATCH] config(8): use sbuf to manage line buffers PR: 245476 Reported by: kevans Reviewed by: imp, kevans MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D24373 --- usr.sbin/config/main.c | 81 ++++++++++++++++++++---------------------- 1 file changed, 39 insertions(+), 42 deletions(-) diff --git a/usr.sbin/config/main.c b/usr.sbin/config/main.c index a7204982f998..e52db432bf65 100644 --- a/usr.sbin/config/main.c +++ b/usr.sbin/config/main.c @@ -113,6 +113,8 @@ struct hdr_list { struct hdr_list *h_next; } *htab; +static struct sbuf *line_buf = NULL; + /* * Config builds a set of files for building a UNIX * system given a description of the desired system. @@ -313,6 +315,29 @@ usage(void) exit(EX_USAGE); } +static void +init_line_buf(void) +{ + if (line_buf == NULL) { + line_buf = sbuf_new(NULL, NULL, 80, SBUF_AUTOEXTEND); + if (line_buf == NULL) { + errx(EXIT_FAILURE, "failed to allocate line buffer"); + } + } else { + sbuf_clear(line_buf); + } +} + +static char * +get_line_buf(void) +{ + if (sbuf_finish(line_buf) != 0) { + errx(EXIT_FAILURE, "failed to generate line buffer, " + "partial line = %s", sbuf_data(line_buf)); + } + return sbuf_data(line_buf); +} + /* * get_word * returns EOF on end of file @@ -322,11 +347,10 @@ usage(void) char * get_word(FILE *fp) { - static char line[160]; int ch; - char *cp; int escaped_nl = 0; + init_line_buf(); begin: while ((ch = getc(fp)) != EOF) if (ch != ' ' && ch != '\t') @@ -345,29 +369,20 @@ get_word(FILE *fp) else return (NULL); } - cp = line; - *cp++ = ch; + sbuf_putc(line_buf, ch); /* Negation operator is a word by itself. */ if (ch == '!') { - *cp = 0; - return (line); + return get_line_buf(); } - while ((ch = getc(fp)) != EOF && cp < line + sizeof(line)) { + while ((ch = getc(fp)) != EOF) { if (isspace(ch)) break; - *cp++ = ch; + sbuf_putc(line_buf, ch); } - if (cp >= line + sizeof(line)) { - line[sizeof(line) - 1] = '\0'; - fprintf(stderr, "config: attempted overflow, partial line: `%s'", - line); - exit(2); - } - *cp = 0; if (ch == EOF) return ((char *)EOF); (void) ungetc(ch, fp); - return (line); + return (get_line_buf()); } /* @@ -378,11 +393,10 @@ get_word(FILE *fp) char * get_quoted_word(FILE *fp) { - static char line[512]; int ch; - char *cp; int escaped_nl = 0; + init_line_buf(); begin: while ((ch = getc(fp)) != EOF) if (ch != ' ' && ch != '\t') @@ -401,7 +415,6 @@ get_quoted_word(FILE *fp) else return (NULL); } - cp = line; if (ch == '"' || ch == '\'') { int quote = ch; @@ -410,9 +423,8 @@ get_quoted_word(FILE *fp) if (ch == quote && !escaped_nl) break; if (ch == '\n' && !escaped_nl) { - *cp = 0; printf("config: missing quote reading `%s'\n", - line); + get_line_buf()); exit(2); } if (ch == '\\' && !escaped_nl) { @@ -420,38 +432,23 @@ get_quoted_word(FILE *fp) continue; } if (ch != quote && escaped_nl) - *cp++ = '\\'; - if (cp >= line + sizeof(line)) { - line[sizeof(line) - 1] = '\0'; - printf( - "config: line buffer overflow reading partial line `%s'\n", - line); - exit(2); - } - *cp++ = ch; + sbuf_putc(line_buf, '\\'); + sbuf_putc(line_buf, ch); escaped_nl = 0; } } else { - *cp++ = ch; - while ((ch = getc(fp)) != EOF && cp < line + sizeof(line)) { + sbuf_putc(line_buf, ch); + while ((ch = getc(fp)) != EOF) { if (isspace(ch)) break; - *cp++ = ch; - } - if (cp >= line + sizeof(line)) { - line[sizeof(line) - 1] = '\0'; - printf( - "config: line buffer overflow reading partial line `%s'\n", - line); - exit(2); + sbuf_putc(line_buf, ch); } if (ch != EOF) (void) ungetc(ch, fp); } - *cp = 0; if (ch == EOF) return ((char *)EOF); - return (line); + return (get_line_buf()); } /*