diff mbox series

[nft,1/4] src: dynamic input_descriptor allocation

Message ID 20190605164652.20199-2-pablo@netfilter.org
State Accepted
Delegated to: Pablo Neira
Headers show
Series split parse and evaluation phase to simplify cache logic | expand

Commit Message

Pablo Neira Ayuso June 5, 2019, 4:46 p.m. UTC
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 |  1 +
 include/parser.h   |  3 ++-
 src/erec.c         | 35 +-----------------------------
 src/parser_bison.y |  1 +
 src/scanner.l      | 63 ++++++++++++++++++++++++++++++++++++------------------
 5 files changed, 47 insertions(+), 56 deletions(-)
diff mbox series

Patch

diff --git a/include/nftables.h b/include/nftables.h
index bb9bb2091716..af2c1ea16cfb 100644
--- a/include/nftables.h
+++ b/include/nftables.h
@@ -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;
diff --git a/include/parser.h b/include/parser.h
index 8e57899eb1a3..a5ae802b288a 100644
--- a/include/parser.h
+++ b/include/parser.h
@@ -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;
diff --git a/src/erec.c b/src/erec.c
index cf543a980bc0..c550a596b38c 100644
--- a/src/erec.c
+++ b/src/erec.c
@@ -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);
 }
 
diff --git a/src/parser_bison.y b/src/parser_bison.y
index 62e76fe617c8..2a39db3148ef 100644
--- a/src/parser_bison.y
+++ b/src/parser_bison.y
@@ -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,
diff --git a/src/scanner.l b/src/scanner.l
index 558bf9209853..d1f6e8799834 100644
--- a/src/scanner.l
+++ b/src/scanner.l
@@ -59,12 +59,12 @@ 
 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);
 }