]> git.ipfire.org Git - thirdparty/nftables.git/commitdiff
src: dynamic input_descriptor allocation
authorPablo Neira Ayuso <pablo@netfilter.org>
Wed, 5 Jun 2019 09:56:11 +0000 (11:56 +0200)
committerPablo Neira Ayuso <pablo@netfilter.org>
Wed, 5 Jun 2019 15:54:21 +0000 (17:54 +0200)
This patch introduces the input descriptor list, that stores the
existing input descriptor objects. These objects are now dynamically
allocated and release from scanner_destroy() path.

Follow up patches that decouple the parsing and the evaluation phases
require this for error reporting as described by b14572f72aac ("erec:
Fix input descriptors for included files"), this patch partially reverts
such partial.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
include/nftables.h
include/parser.h
src/erec.c
src/parser_bison.y
src/scanner.l

index bb9bb2091716d36ce93618d23e0939be282f856b..af2c1ea16cfb5068c55ef78ea6955a7bc12dd2b0 100644 (file)
@@ -165,6 +165,7 @@ enum input_descriptor_types {
  * @line_offset:       offset of the current line to the beginning
  */
 struct input_descriptor {
+       struct list_head                list;
        struct location                 location;
        enum input_descriptor_types     type;
        const char                      *name;
index 8e57899eb1a3d2bd3bd3bf7fc3e2b8b46f66b535..a5ae802b288abcb2ba514fb5de0b98d09def67cf 100644 (file)
@@ -15,8 +15,9 @@
 
 struct parser_state {
        struct input_descriptor         *indesc;
-       struct input_descriptor         indescs[MAX_INCLUDE_DEPTH];
+       struct input_descriptor         *indescs[MAX_INCLUDE_DEPTH];
        unsigned int                    indesc_idx;
+       struct list_head                indesc_list;
 
        struct list_head                *msgs;
        unsigned int                    nerrs;
index cf543a980bc040d9cc587f705f420c08ad101e58..c550a596b38c83a52eb410c166a27594e3737dff 100644 (file)
@@ -34,50 +34,17 @@ static const char * const error_record_names[] = {
        [EREC_ERROR]            = "Error"
 };
 
-static void input_descriptor_destroy(const struct input_descriptor *indesc)
-{
-       if (indesc->location.indesc &&
-           indesc->location.indesc->type != INDESC_INTERNAL) {
-               input_descriptor_destroy(indesc->location.indesc);
-       }
-       if (indesc->name)
-               xfree(indesc->name);
-       xfree(indesc);
-}
-
-static struct input_descriptor *input_descriptor_dup(const struct input_descriptor *indesc)
-{
-       struct input_descriptor *dup_indesc;
-
-       dup_indesc = xmalloc(sizeof(struct input_descriptor));
-       *dup_indesc = *indesc;
-
-       if (indesc->location.indesc &&
-           indesc->location.indesc->type != INDESC_INTERNAL)
-               dup_indesc->location.indesc = input_descriptor_dup(indesc->location.indesc);
-
-       if (indesc->name)
-               dup_indesc->name = xstrdup(indesc->name);
-
-       return dup_indesc;
-}
-
 void erec_add_location(struct error_record *erec, const struct location *loc)
 {
        assert(erec->num_locations < EREC_LOCATIONS_MAX);
        erec->locations[erec->num_locations] = *loc;
-       erec->locations[erec->num_locations].indesc = input_descriptor_dup(loc->indesc);
+       erec->locations[erec->num_locations].indesc = loc->indesc;
        erec->num_locations++;
 }
 
 void erec_destroy(struct error_record *erec)
 {
-       unsigned int i;
-
        xfree(erec->msg);
-       for (i = 0; i < erec->num_locations; i++) {
-               input_descriptor_destroy(erec->locations[i].indesc);
-       }
        xfree(erec);
 }
 
index 62e76fe617c8bda01e41873790a3273ac9dea0b6..2a39db3148efee14c77ac21b1d9f178518d64e11 100644 (file)
@@ -50,6 +50,7 @@ void parser_init(struct nft_ctx *nft, struct parser_state *state,
        state->scopes[0] = scope_init(&state->top_scope, NULL);
        state->ectx.nft = nft;
        state->ectx.msgs = msgs;
+       init_list_head(&state->indesc_list);
 }
 
 static void yyerror(struct location *loc, struct nft_ctx *nft, void *scanner,
index 558bf920985362a9e8146b8cc231491c1578f6ed..d1f6e8799834a29a4e5eae949bb4defc017bc2df 100644 (file)
 static void scanner_pop_buffer(yyscan_t scanner);
 
 
-static void init_pos(struct parser_state *state)
+static void init_pos(struct input_descriptor *indesc)
 {
-       state->indesc->lineno           = 1;
-       state->indesc->column           = 1;
-       state->indesc->token_offset     = 0;
-       state->indesc->line_offset      = 0;
+       indesc->lineno          = 1;
+       indesc->column          = 1;
+       indesc->token_offset    = 0;
+       indesc->line_offset     = 0;
 }
 
 static void update_pos(struct parser_state *state, struct location *loc,
@@ -656,13 +656,14 @@ static void scanner_pop_buffer(yyscan_t scanner)
        struct parser_state *state = yyget_extra(scanner);
 
        yypop_buffer_state(scanner);
-       state->indesc = &state->indescs[--state->indesc_idx - 1];
+       state->indesc = state->indescs[--state->indesc_idx];
 }
 
 static struct error_record *scanner_push_file(struct nft_ctx *nft, void *scanner,
                                              const char *filename, const struct location *loc)
 {
        struct parser_state *state = yyget_extra(scanner);
+       struct input_descriptor *indesc;
        YY_BUFFER_STATE b;
 
        if (state->indesc_idx == MAX_INCLUDE_DEPTH)
@@ -672,12 +673,18 @@ static struct error_record *scanner_push_file(struct nft_ctx *nft, void *scanner
        b = yy_create_buffer(nft->f[state->indesc_idx], YY_BUF_SIZE, scanner);
        yypush_buffer_state(b, scanner);
 
-       state->indesc = &state->indescs[state->indesc_idx++];
+       indesc = xzalloc(sizeof(struct input_descriptor));
+
        if (loc != NULL)
-               state->indesc->location = *loc;
-       state->indesc->type     = INDESC_FILE;
-       state->indesc->name     = xstrdup(filename);
-       init_pos(state);
+               indesc->location = *loc;
+       indesc->type    = INDESC_FILE;
+       indesc->name    = xstrdup(filename);
+       init_pos(indesc);
+
+       state->indescs[state->indesc_idx] = indesc;
+       state->indesc = state->indescs[state->indesc_idx++];
+       list_add_tail(&indesc->list, &state->indesc_list);
+
        return NULL;
 }
 
@@ -874,39 +881,52 @@ void scanner_push_buffer(void *scanner, const struct input_descriptor *indesc,
        struct parser_state *state = yyget_extra(scanner);
        YY_BUFFER_STATE b;
 
-       state->indesc = &state->indescs[state->indesc_idx++];
+       state->indesc = xzalloc(sizeof(struct input_descriptor));
+       state->indescs[state->indesc_idx] = state->indesc;
+       state->indesc_idx++;
+
        memcpy(state->indesc, indesc, sizeof(*state->indesc));
        state->indesc->data = buffer;
        state->indesc->name = NULL;
+       list_add_tail(&state->indesc->list, &state->indesc_list);
 
        b = yy_scan_string(buffer, scanner);
        assert(b != NULL);
-       init_pos(state);
+       init_pos(state->indesc);
 }
 
 void *scanner_init(struct parser_state *state)
 {
        yyscan_t scanner;
 
-       state->indesc = state->indescs;
-
        yylex_init_extra(state, &scanner);
        yyset_out(NULL, scanner);
 
        return scanner;
 }
 
+static void input_descriptor_destroy(const struct input_descriptor *indesc)
+{
+       if (indesc->name)
+               xfree(indesc->name);
+       xfree(indesc);
+}
+
+static void input_descriptor_list_destroy(struct parser_state *state)
+{
+       struct input_descriptor *indesc, *next;
+
+       list_for_each_entry_safe(indesc, next, &state->indesc_list, list) {
+               list_del(&indesc->list);
+               input_descriptor_destroy(indesc);
+       }
+}
+
 void scanner_destroy(struct nft_ctx *nft)
 {
        struct parser_state *state = yyget_extra(nft->scanner);
 
        do {
-               struct input_descriptor *inpdesc =
-                       &state->indescs[state->indesc_idx];
-               if (inpdesc && inpdesc->name) {
-                       xfree(inpdesc->name);
-                       inpdesc->name = NULL;
-               }
                yypop_buffer_state(nft->scanner);
 
                if (nft->f[state->indesc_idx]) {
@@ -915,5 +935,6 @@ void scanner_destroy(struct nft_ctx *nft)
                }
        } while (state->indesc_idx--);
 
+       input_descriptor_list_destroy(state);
        yylex_destroy(nft->scanner);
 }