awk: Fix overly permissive func arg list parsing
No binary (build failed)
—
(log yok)
| @@ -1613,12 +1613,25 @@ static void parse_program(char *p) | |
| f = newfunc(t_string); | |
| f->body.first = NULL; | |
| f->nargs = 0; | |
| - | while (next_token(TC_VARIABLE | TC_SEQTERM) & TC_VARIABLE) { |
| + | /* Match func arg list: a comma sep list of >= 0 args, and a close paren */ |
| + | while (next_token(TC_VARIABLE | TC_SEQTERM | TC_COMMA)) { |
| + | /* Either an empty arg list, or trailing comma from prev iter |
| + | * must be followed by an arg */ |
| + | if (f->nargs == 0 && t_tclass == TC_SEQTERM) |
| + | break; |
| + | |
| + | /* TC_SEQSTART/TC_COMMA must be followed by TC_VARIABLE */ |
| + | if (t_tclass != TC_VARIABLE) |
| + | syntax_error(EMSG_UNEXP_TOKEN); |
| + | |
| v = findvar(ahash, t_string); | |
| v->x.aidx = f->nargs++; | |
| + | /* Arg followed either by end of arg list or 1 comma */ |
| if (next_token(TC_COMMA | TC_SEQTERM) & TC_SEQTERM) | |
| break; | |
| + | if (t_tclass != TC_COMMA) |
| + | syntax_error(EMSG_UNEXP_TOKEN); |
| } | |
| seq = &f->body; | |
| chain_group(); | |
| @@ -280,6 +280,18 @@ testing "awk 'delete a[v--]' evaluates v-- once" \ | |
| " \ | |
| "" "" | |
| + | testing "awk func arg parsing 1" \ |
| + | "awk 'func f(,) { }' 2>&1" "awk: cmd. line:1: Unexpected token\n" "" "" |
| + | |
| + | testing "awk func arg parsing 2" \ |
| + | "awk 'func f(a,,b) { }' 2>&1" "awk: cmd. line:1: Unexpected token\n" "" "" |
| + | |
| + | testing "awk func arg parsing 3" \ |
| + | "awk 'func f(a,) { }' 2>&1" "awk: cmd. line:1: Unexpected token\n" "" "" |
| + | |
| + | testing "awk func arg parsing 4" \ |
| + | "awk 'func f(a b) { }' 2>&1" "awk: cmd. line:1: Unexpected token\n" "" "" |
| + | |
| testing "awk handles empty ()" \ | |
| "awk 'BEGIN {print()}' 2>&1" "awk: cmd. line:1: Empty sequence\n" "" "" | |