From a24862fc405e2a64b203b9bf3ec59b272f685379 Mon Sep 17 00:00:00 2001 From: Tobias Stoeckmann Date: Tue, 30 Nov 2021 20:08:16 +0000 Subject: Improved error handling in config parser. - Escaped newlines confused column counter - An unclosed quote could have been logged multiple times - Signed data types could overflow, which is undefined behavior ok tedu --- usr.bin/doas/doas.c | 4 ++-- usr.bin/doas/doas.h | 4 ++-- usr.bin/doas/parse.y | 37 +++++++++++++++++++++---------------- 3 files changed, 25 insertions(+), 20 deletions(-) (limited to 'usr.bin') diff --git a/usr.bin/doas/doas.c b/usr.bin/doas/doas.c index 4ceb6b99b92..0172e0c1cf7 100644 --- a/usr.bin/doas/doas.c +++ b/usr.bin/doas/doas.c @@ -1,4 +1,4 @@ -/* $OpenBSD: doas.c,v 1.92 2021/10/13 17:41:14 millert Exp $ */ +/* $OpenBSD: doas.c,v 1.93 2021/11/30 20:08:15 tobias Exp $ */ /* * Copyright (c) 2015 Ted Unangst * @@ -172,7 +172,7 @@ parseconfig(const char *filename, int checkperms) yyparse(); fclose(yyfp); - if (parse_errors) + if (parse_error) exit(1); } diff --git a/usr.bin/doas/doas.h b/usr.bin/doas/doas.h index 3a9bf4d4de2..b98fe353b18 100644 --- a/usr.bin/doas/doas.h +++ b/usr.bin/doas/doas.h @@ -1,4 +1,4 @@ -/* $OpenBSD: doas.h,v 1.18 2021/09/07 13:46:07 jcs Exp $ */ +/* $OpenBSD: doas.h,v 1.19 2021/11/30 20:08:15 tobias Exp $ */ /* * Copyright (c) 2015 Ted Unangst * @@ -27,7 +27,7 @@ struct rule { extern struct rule **rules; extern size_t nrules; -extern int parse_errors; +extern int parse_error; extern const char *formerpath; diff --git a/usr.bin/doas/parse.y b/usr.bin/doas/parse.y index eaaf8c4b2e6..30d4c7d41c7 100644 --- a/usr.bin/doas/parse.y +++ b/usr.bin/doas/parse.y @@ -1,4 +1,4 @@ -/* $OpenBSD: parse.y,v 1.29 2021/01/27 17:02:50 millert Exp $ */ +/* $OpenBSD: parse.y,v 1.30 2021/11/30 20:08:15 tobias Exp $ */ /* * Copyright (c) 2015 Ted Unangst * @@ -18,6 +18,7 @@ %{ #include #include +#include #include #include #include @@ -39,8 +40,8 @@ typedef struct { const char **strlist; const char *str; }; - int lineno; - int colno; + unsigned long lineno; + unsigned long colno; } yystype; #define YYSTYPE yystype @@ -50,7 +51,7 @@ struct rule **rules; size_t nrules; static size_t maxrules; -int parse_errors = 0; +int parse_error = 0; static void yyerror(const char *, ...); static int yylex(void); @@ -198,8 +199,8 @@ yyerror(const char *fmt, ...) va_start(va, fmt); vfprintf(stderr, fmt, va); va_end(va); - fprintf(stderr, " at line %d\n", yylval.lineno + 1); - parse_errors++; + fprintf(stderr, " at line %lu\n", yylval.lineno + 1); + parse_error = 1; } static struct keyword { @@ -222,7 +223,8 @@ int yylex(void) { char buf[1024], *ebuf, *p, *str; - int c, quotes = 0, escape = 0, qpos = -1, nonkw = 0; + int c, quoted = 0, quotes = 0, qerr = 0, escape = 0, nonkw = 0; + unsigned long qpos = 0; size_t i; p = buf; @@ -258,7 +260,7 @@ repeat: for (;; c = getc(yyfp), yylval.colno++) { switch (c) { case '\0': - yyerror("unallowed character NUL in column %d", + yyerror("unallowed character NUL in column %lu", yylval.colno + 1); escape = 0; continue; @@ -268,26 +270,27 @@ repeat: continue; break; case '\n': - if (quotes) - yyerror("unterminated quotes in column %d", + if (quotes && !qerr) { + yyerror("unterminated quotes in column %lu", qpos + 1); + qerr = 1; + } if (escape) { nonkw = 1; escape = 0; - yylval.colno = 0; + yylval.colno = ULONG_MAX; yylval.lineno++; continue; } goto eow; case EOF: if (escape) - yyerror("unterminated escape in column %d", + yyerror("unterminated escape in column %lu", yylval.colno); - if (quotes) - yyerror("unterminated quotes in column %d", + if (quotes && !qerr) + yyerror("unterminated quotes in column %lu", qpos + 1); goto eow; - /* FALLTHROUGH */ case '{': case '}': case '#': @@ -298,9 +301,11 @@ repeat: break; case '"': if (!escape) { + quoted = 1; quotes = !quotes; if (quotes) { nonkw = 1; + qerr = 0; qpos = yylval.colno; } continue; @@ -326,7 +331,7 @@ eow: */ if (c == EOF) goto eof; - else if (qpos == -1) /* accept, e.g., empty args: cmd foo args "" */ + else if (!quoted) /* accept, e.g., empty args: cmd foo args "" */ goto repeat; } if (!nonkw) { -- cgit v1.2.3