summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnatole Denis <anatole@rezel.net>2017-02-21 15:48:05 +0100
committerPablo Neira Ayuso <pablo@netfilter.org>2017-02-25 13:40:14 +0100
commitb14572f72aac80ed06d3fac0259896ecabb51fd1 (patch)
tree02106b22442c06e11cd12cc589cc7c5ffbf24fa3
parentb2d7b78af50d199201e7e0d6de7c1ba9ba471c12 (diff)
erec: Fix input descriptors for included files
Currently, when creating an error record (erec), the current location in the file is duplicated, but not the input_descriptor inside it. Input descriptors are added and removed by the parser when including files, and memory references in the error record thus become incorrect when a subsequent file is included. This patch copies the input descriptors recursively to ensure each erec has the correct chain of input descriptors at the time of printing. For example: badinclude.nft: ``` include "error.nft" include "empty.nft" ``` a.nft: ``` add rule t c obvious syntax error ``` b.nft: (empty file) Results in the last included file being referenced and quoted for all errors $ nft -f badinclude.nft In file included from badinclude.nft:2:1-20: ./empty.nft:1:34-34: Error: syntax error, unexpected newline ^ Expected behavior: $ nft -f badinclude.nft -I. In file included from badinclude.nft:1:1-20: ./error.nft:1:34-34: Error: syntax error, unexpected newline add rule t c obvious syntax error ^ Signed-off-by: Anatole Denis <anatole@rezel.net> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-rw-r--r--src/erec.c32
1 files changed, 31 insertions, 1 deletions
diff --git a/src/erec.c b/src/erec.c
index 36032165..eacdd97a 100644
--- a/src/erec.c
+++ b/src/erec.c
@@ -33,15 +33,45 @@ static const char *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);
+ }
+ 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);
+
+ 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] = *loc;
+ erec->locations[erec->num_locations].indesc = input_descriptor_dup(loc->indesc);
+ erec->num_locations++;
}
static 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);
}