make things a little more convenient.

a backslash indicates escape, which we don't need to support for keywords. so
always set nonkw for those tokens. this lets "permit \permit" work.

there are no keywords after the args keyword, so we can create a lexer
backdoor. this lets "permit user cmd ls args cmd" to work without quoting.


Index: parse.y
===================================================================
RCS file: /cvs/src/usr.bin/doas/parse.y,v
retrieving revision 1.26
diff -u -p -r1.26 parse.y
--- parse.y     2 Jan 2017 01:40:20 -0000       1.26
+++ parse.y     27 Aug 2017 21:23:57 -0000
@@ -51,6 +51,7 @@ int nrules;
 static int maxrules;
 
 int parse_errors = 0;
+int inargs = 0;
 
 static void yyerror(const char *, ...);
 static int yylex(void);
@@ -103,6 +104,7 @@ rule:               action ident target cmd {
                                        errx(1, "can't allocate rules");
                        }
                        rules[nrules++] = r;
+                       inargs = 0;
                } ;
 
 action:                TPERMIT options {
@@ -180,7 +182,7 @@ cmd:                /* optional */ {
 
 args:          /* empty */ {
                        $$.cmdargs = NULL;
-               } | TARGS strlist {
+               } | TARGS { inargs = 1; } strlist {
                        $$.cmdargs = $2.strlist;
                } ;
 
@@ -259,8 +261,10 @@ repeat:
                        continue;
                case '\\':
                        escape = !escape;
-                       if (escape)
+                       if (escape) {
+                               nonkw = 1;
                                continue;
+                       }
                        break;
                case '\n':
                        if (quotes)
@@ -324,7 +328,7 @@ eow:
                else if (qpos == -1)    /* accept, e.g., empty args: cmd foo 
args "" */
                        goto repeat;
        }
-       if (!nonkw) {
+       if (!inargs && !nonkw) {
                for (i = 0; i < sizeof(keywords) / sizeof(keywords[0]); i++) {
                        if (strcmp(buf, keywords[i].word) == 0)
                                return keywords[i].token;

Reply via email to