summaryrefslogtreecommitdiff
path: root/lib/command_match.c
diff options
context:
space:
mode:
authorQuentin Young <qlyoung@cumulusnetworks.com>2016-11-15 22:15:18 +0000
committerQuentin Young <qlyoung@cumulusnetworks.com>2016-11-15 22:15:18 +0000
commit3c7ca60c410fe87dc10ab5a26049b89e15dada78 (patch)
tree49bbc13ccc7b35544c8f0c8a93f5dd660769edd5 /lib/command_match.c
parentfefa0d82145890019b5cf66bc2e2323f603f6d79 (diff)
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 <qlyoung@cumulusnetworks.com>
Diffstat (limited to 'lib/command_match.c')
-rw-r--r--lib/command_match.c10
1 files changed, 8 insertions, 2 deletions
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