From: Quentin Young Date: Tue, 15 Nov 2016 22:15:18 +0000 (+0000) Subject: lib: Fix nondeterministic command matches in rare cases X-Git-Tag: frr-3.0-branchpoint~129^2~29 X-Git-Url: https://git.puffer.fish/?a=commitdiff_plain;h=3c7ca60c410fe87dc10ab5a26049b89e15dada78;p=mirror%2Ffrr.git lib: Fix nondeterministic command matches in rare cases When a user erroneously defines two commands which can match the same input and at least one of the tokens defined last in the command is a selector or option, the matcher does not detect an ambiguous match and matches the command installed first (leftmost in the graph). Fix is to do a full walkthrough of the follow set when matching the final token in a command to check that there is exactly one possible match, and to throw an ambiguity error otherwise. Signed-off-by: Quentin Young --- diff --git a/lib/command_match.c b/lib/command_match.c index 82090be732..06a50656b6 100644 --- a/lib/command_match.c +++ b/lib/command_match.c @@ -240,6 +240,11 @@ command_match_r (struct graph_node *start, vector vline, unsigned int n) struct cmd_token *tok = gn->data; if (tok->type == END_TKN) { + if (currbest) // there is more than one END_TKN in the follow set + { + ambiguous = 1; + break; + } currbest = list_new(); // node should have one child node with the element struct graph_node *leaf = vector_slot (gn->to, 0); @@ -251,9 +256,10 @@ command_match_r (struct graph_node *start, vector vline, unsigned int n) struct cmd_element *el = leaf->data; listnode_add (currbest, el); currbest->del = (void (*)(void *)) &del_cmd_token; - break; + // do not break immediately; continue walking through the follow set + // to ensure that there is exactly one END_TKN } - else continue; + continue; } // else recurse on candidate child node