]> git.ipfire.org Git - thirdparty/nftables.git/commitdiff
segtree: disantangle get_set_interval_end()
authorPablo Neira Ayuso <pablo@netfilter.org>
Wed, 3 Oct 2018 10:09:09 +0000 (12:09 +0200)
committerPablo Neira Ayuso <pablo@netfilter.org>
Wed, 3 Oct 2018 10:19:35 +0000 (12:19 +0200)
This function overrides the left pointer. Instead update this function
to return the range that we found to enclose the left element. Note that
we may not find a closing right element - therefore, it is a standalone
element - in that case this function returns NULL.

Reported-by: Phil Sutter <phil@nwl.cc>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
src/segtree.c

index 288b01f420a48addc7d813d79460903bf697ebcc..0d53c83fd837eb7ed09ae60fe90e2de9fb40f98d 100644 (file)
@@ -681,9 +681,9 @@ static struct expr *get_set_interval_end(const struct table *table,
                                         const char *set_name,
                                         struct expr *left)
 {
+       struct expr *i, *range = NULL;
        struct set *set;
        mpz_t low, high;
-       struct expr *i;
 
        set = set_lookup(table, set_name);
        mpz_init2(low, set->key->len);
@@ -694,9 +694,9 @@ static struct expr *get_set_interval_end(const struct table *table,
                case EXPR_RANGE:
                        range_expr_value_low(low, i);
                        if (mpz_cmp(low, left->key->value) == 0) {
-                               left = range_expr_alloc(&internal_location,
-                                                       expr_clone(left->key),
-                                                       expr_clone(i->key->right));
+                               range = range_expr_alloc(&internal_location,
+                                                        expr_clone(left->key),
+                                                        expr_clone(i->key->right));
                                break;
                        }
                        break;
@@ -708,12 +708,12 @@ static struct expr *get_set_interval_end(const struct table *table,
        mpz_clear(low);
        mpz_clear(high);
 
-       return left;
+       return range;
 }
 
 int get_set_decompose(struct table *table, struct set *set)
 {
-       struct expr *i, *next, *new;
+       struct expr *i, *next, *range;
        struct expr *left = NULL;
        struct expr *new_init;
 
@@ -724,28 +724,35 @@ int get_set_decompose(struct table *table, struct set *set)
                        list_del(&left->list);
                        list_del(&i->list);
                        mpz_sub_ui(i->key->value, i->key->value, 1);
-                       new = get_set_interval_find(table, set->handle.set.name,
+                       range = get_set_interval_find(table, set->handle.set.name,
                                                    left, i);
-                       if (!new) {
+                       if (!range) {
                                errno = ENOENT;
                                return -1;
                        }
 
-                       compound_expr_add(new_init, new);
+                       compound_expr_add(new_init, range);
                        left = NULL;
                } else {
                        if (left) {
-                               left = get_set_interval_end(table,
-                                                           set->handle.set.name,
-                                                           left);
-                               compound_expr_add(new_init, left);
+                               range = get_set_interval_end(table,
+                                                            set->handle.set.name,
+                                                            left);
+                               if (range)
+                                       compound_expr_add(new_init, range);
+                               else
+                                       compound_expr_add(new_init,
+                                                         expr_clone(left));
                        }
                        left = i;
                }
        }
        if (left) {
-               left = get_set_interval_end(table, set->handle.set.name, left);
-               compound_expr_add(new_init, left);
+               range = get_set_interval_end(table, set->handle.set.name, left);
+               if (range)
+                       compound_expr_add(new_init, left);
+               else
+                       compound_expr_add(new_init, expr_clone(left));
        }
 
        set->init = new_init;