--- include/parser.h | 10 ++++++++-- src/libnftables.c | 2 ++ src/parser_bison.y | 14 ++++++++++---- src/rule.c | 1 + src/scanner.l | 18 +++++++++++++++++- 5 files changed, 38 insertions(+), 7 deletions(-) diff --git a/include/parser.h b/include/parser.h index ea41ca0..1f3eb5f 100644 --- a/include/parser.h +++ b/include/parser.h @@ -4,14 +4,14 @@ #include <list.h> #include <rule.h> // FIXME -#define MAX_INCLUDE_DEPTH 16 +#define MAX_INCLUDE_DEPTH 64 #define TABSIZE 8 #define YYLTYPE struct location #define YYLTYPE_IS_TRIVIAL 0 #define YYENABLE_NLS 0 -#define SCOPE_NEST_MAX 3 +#define SCOPE_NEST_MAX (MAX_INCLUDE_DEPTH + 3) struct parser_state { struct input_descriptor *indesc; @@ -33,6 +33,12 @@ struct mnl_socket; extern void parser_init(struct nft_ctx *nft, struct parser_state *state, struct list_head *msgs, struct list_head *cmds); +extern void parser_destroy(struct parser_state *state); + +extern void open_scope(struct parser_state *state, struct scope *scope); +extern void close_scope(struct parser_state *state); +extern struct scope *current_scope(const struct parser_state *state); + extern int nft_parse(struct nft_ctx *ctx, void *, struct parser_state *state); extern void *scanner_init(struct parser_state *state); diff --git a/src/libnftables.c b/src/libnftables.c index 5bc7ba0..54ad614 100644 --- a/src/libnftables.c +++ b/src/libnftables.c @@ -411,6 +411,7 @@ static int nft_parse_bison_buffer(struct nft_ctx *nft, char *buf, size_t buflen, list_for_each_entry(cmd, cmds, list) nft_cmd_expand(cmd); + parser_destroy(nft->state); return 0; } @@ -433,6 +434,7 @@ static int nft_parse_bison_filename(struct nft_ctx *nft, const char *filename, list_for_each_entry(cmd, cmds, list) nft_cmd_expand(cmd); + parser_destroy(nft->state); return 0; } diff --git a/src/parser_bison.y b/src/parser_bison.y index d13eaa6..16a1f75 100644 --- a/src/parser_bison.y +++ b/src/parser_bison.y @@ -51,27 +51,33 @@ void parser_init(struct nft_ctx *nft, struct parser_state *state, state->ectx.octx = &nft->output; } +void parser_destroy(struct parser_state *state) +{ + scope_release(state->scopes[0]); +} + static void yyerror(struct location *loc, struct nft_ctx *nft, void *scanner, struct parser_state *state, const char *s) { erec_queue(error(loc, "%s", s), state->msgs); } -static struct scope *current_scope(const struct parser_state *state) +struct scope *current_scope(const struct parser_state *state) { return state->scopes[state->scope]; } -static void open_scope(struct parser_state *state, struct scope *scope) +void open_scope(struct parser_state *state, struct scope *scope) { assert(state->scope < array_size(state->scopes) - 1); scope_init(scope, current_scope(state)); state->scopes[++state->scope] = scope; } -static void close_scope(struct parser_state *state) +void close_scope(struct parser_state *state) { assert(state->scope > 0); + scope_release(state->scopes[state->scope]); state->scope--; } @@ -778,6 +784,7 @@ common_block : INCLUDE QUOTED_STRING stmt_separator erec_queue(error(&@2, "redefinition of symbol '%s'", $2), state->msgs); xfree($2); + expr_free($4); YYERROR; } @@ -840,7 +847,6 @@ line : common_block { $$ = NULL; } if (state->nerrs) YYABORT; $$ = NULL; - YYACCEPT; } ; diff --git a/src/rule.c b/src/rule.c index 3e8dea4..38529af 100644 --- a/src/rule.c +++ b/src/rule.c @@ -17,6 +17,7 @@ #include <errno.h> #include <statement.h> +#include <parser.h> #include <rule.h> #include <utils.h> #include <netdb.h> diff --git a/src/scanner.l b/src/scanner.l index 6a861cf..e6e255d 100644 --- a/src/scanner.l +++ b/src/scanner.l @@ -629,7 +629,15 @@ addrstring ({macaddr}|{ip4addr}|{ip6addr}) {comment} <<EOF>> { - update_pos(yyget_extra(yyscanner), yylloc, 1); + struct parser_state *state = yyget_extra(yyscanner); + struct scope *scope = current_scope(state); + update_pos(state, yylloc, 1); + /* only close scope if file was included, skip buffer parsing + since it does not create new scope */ + if (state->indesc && state->indesc->name) { + close_scope(state); + xfree(scope); + } scanner_pop_buffer(yyscanner); if (YY_CURRENT_BUFFER == NULL) return TOKEN_EOF; @@ -644,6 +652,10 @@ static void scanner_pop_buffer(yyscan_t scanner) struct parser_state *state = yyget_extra(scanner); yypop_buffer_state(scanner); + if (state->indesc && state->indesc->name) { + xfree(state->indesc->name); + state->indesc->name = NULL; + } state->indesc = &state->indescs[--state->indesc_idx - 1]; } @@ -651,6 +663,7 @@ static struct error_record *scanner_push_file(void *scanner, const char *filenam FILE *f, const struct location *loc) { struct parser_state *state = yyget_extra(scanner); + struct scope *scope = NULL; YY_BUFFER_STATE b; if (state->indesc_idx == MAX_INCLUDE_DEPTH) { @@ -668,6 +681,9 @@ static struct error_record *scanner_push_file(void *scanner, const char *filenam state->indesc->type = INDESC_FILE; state->indesc->name = xstrdup(filename); init_pos(state); + scope = xzalloc(sizeof(*scope)); + init_list_head(&scope->symbols); + open_scope(state, scope); return NULL; } -- 2.13.6 -- To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html