diff options
author | David Lamparter <equinox@diac24.net> | 2019-06-25 13:34:12 +0200 |
---|---|---|
committer | David Lamparter <equinox@diac24.net> | 2019-06-25 13:35:21 +0200 |
commit | eb44e1aac0811da16766bdea255ffef93e2a5b23 (patch) | |
tree | 4a715b14d03b0002111328000d55f41ee9b814d0 /lib/command_parse.y | |
parent | Merge pull request #4597 from FRRouting/revert-3775-ospf_missing_interface_ha... (diff) | |
download | frr-eb44e1aac0811da16766bdea255ffef93e2a5b23.tar.xz frr-eb44e1aac0811da16766bdea255ffef93e2a5b23.zip |
lib: add a check for {[...]} in DEFUNs
Our command matcher doesn't handle {[...]} correctly; let's warn about
it so the DEFUN can be changed to [{...}] (which does work as expected.)
Fixes: #4594
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
Diffstat (limited to 'lib/command_parse.y')
-rw-r--r-- | lib/command_parse.y | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/lib/command_parse.y b/lib/command_parse.y index 1b304a98b..062a4bb30 100644 --- a/lib/command_parse.y +++ b/lib/command_parse.y @@ -46,6 +46,7 @@ %code requires { #include "config.h" + #include <stdbool.h> #include <stdlib.h> #include <string.h> #include <ctype.h> @@ -140,6 +141,8 @@ static void cleanup (struct parser_ctx *ctx); + static void loopcheck(struct parser_ctx *ctx, struct subgraph *sg); + #define scanner ctx->scanner } @@ -335,6 +338,7 @@ selector: '{' selector_seq_seq '}' varname_token * just use [{a|b}] if neccessary, that will work perfectly fine, and reason * #1 is good enough to keep it this way. */ + loopcheck(ctx, &$$); cmd_token_varname_set ($2.end->data, $4); XFREE (MTYPE_LEX, $4); }; @@ -396,6 +400,38 @@ cmd_graph_parse (struct graph *graph, struct cmd_element *cmd) /* parser helper functions */ +static bool loopcheck_inner(struct graph_node *start, struct graph_node *node, + struct graph_node *end, size_t depth) +{ + size_t i; + bool ret; + + /* safety check */ + if (depth++ == 64) + return true; + + for (i = 0; i < vector_active(node->to); i++) { + struct graph_node *next = vector_slot(node->to, i); + struct cmd_token *tok = next->data; + + if (next == end || next == start) + return true; + if (tok->type < SPECIAL_TKN) + continue; + ret = loopcheck_inner(start, next, end, depth); + if (ret) + return true; + } + return false; +} + +static void loopcheck(struct parser_ctx *ctx, struct subgraph *sg) +{ + if (loopcheck_inner(sg->start, sg->start, sg->end, 0)) + zlog_err("FATAL: '%s': {} contains an empty path! Use [{...}]", + ctx->el->string); +} + void yyerror (CMD_YYLTYPE *loc, struct parser_ctx *ctx, char const *msg) { |