]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
handle end of list conditions, too, and other fixes
authorAlan T. DeKok <aland@freeradius.org>
Tue, 7 Dec 2021 16:43:39 +0000 (11:43 -0500)
committerAlan T. DeKok <aland@freeradius.org>
Tue, 7 Dec 2021 17:13:57 +0000 (12:13 -0500)
src/lib/util/edit.c

index b910200249308d81a3696841cd5a5864d05d7031..1a9b03867fa5f9e6aafed6065a1ee6e053abd487 100644 (file)
@@ -704,6 +704,23 @@ static int list_union(fr_edit_list_t *el, fr_pair_t *dst, fr_pair_list_t *src)
                a = fr_dcursor_current(&cursor1);
                b = fr_dcursor_current(&cursor2);
 
+               /*
+                *      B is done, so we stop processing the union.
+                */
+               if (!b) break;
+
+               /*
+                *      A is done, so we always union in B at the end of A.
+                */
+               if (!a) {
+                       if (fr_edit_list_insert_pair_tail(el, &dst->children, fr_pair_copy(dst, b)) < 0) {
+                               return -1;
+                       }
+
+                       fr_dcursor_next(&cursor2);
+                       continue;
+               }
+
                rcode = fr_pair_cmp_by_parent_num(a, b);
 
                /*
@@ -748,12 +765,30 @@ static int list_union(fr_edit_list_t *el, fr_pair_t *dst, fr_pair_list_t *src)
                 */
                fr_assert(a->da == b->da);
 
+               /*
+                *      UNION the children, and then don't bother
+                *      copying B to A, as its children have already
+                *      been added in.
+                */
                if (fr_type_is_structural(a->vp_type)) {
                        rcode = list_union(el, a, &b->children);
                        if (rcode < 0) return rcode;
+
+                       fr_dcursor_next(&cursor1);
+                       fr_dcursor_next(&cursor2);
+                       continue;
                }
 
-               fr_dcursor_next(&cursor1);
+               /*
+                *
+                */
+               if (fr_edit_list_insert_pair_after(el, &dst->children, a, fr_pair_copy(dst, b)) < 0) {
+                       return -1;
+               }
+
+               fr_dcursor_next(&cursor1); /* skip A */
+               fr_dcursor_next(&cursor1); /* skip copy of B we just added */
+
                fr_dcursor_next(&cursor2);
        }
 
@@ -781,6 +816,23 @@ static int list_merge_lhs(fr_edit_list_t *el, fr_pair_t *dst, fr_pair_list_t *sr
                a = fr_dcursor_current(&cursor1);
                b = fr_dcursor_current(&cursor2);
 
+               /*
+                *      B is done, so we stop processing the merge.
+                */
+               if (!b) break;
+
+               /*
+                *      A is done, so we always merge in B at the end of A.
+                */
+               if (!a) {
+                       if (fr_edit_list_insert_pair_tail(el, &dst->children, fr_pair_copy(dst, b)) < 0) {
+                               return -1;
+                       }
+
+                       fr_dcursor_next(&cursor2);
+                       continue;
+               }
+
                rcode = fr_pair_cmp_by_parent_num(a, b);
 
                /*