]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
allow for and test &Foo := &bar[*]
authorAlan T. DeKok <aland@freeradius.org>
Wed, 17 Aug 2022 15:59:08 +0000 (11:59 -0400)
committerAlan T. DeKok <aland@freeradius.org>
Wed, 17 Aug 2022 15:59:24 +0000 (11:59 -0400)
src/lib/unlang/edit.c
src/tests/keywords/edit-leaf-star

index f33e5d7ce8f75dd1e9195a97f4344ca8f8f78d0e..21263391994033ea9996c2220ef1aa51a2909053 100644 (file)
@@ -462,6 +462,7 @@ static int apply_edits_to_leaf(request_t *request, edit_map_t *current, map_t co
         *      &Foo := { a, b, c }
         */
        if (!current->rhs.vpt) {
+       apply_list:
                fr_assert(current->lhs.vp_parent != NULL);
 
                if (fr_edit_list_pair_delete_by_da(current->el, &current->lhs.vp_parent->vp_group,
@@ -487,6 +488,8 @@ static int apply_edits_to_leaf(request_t *request, edit_map_t *current, map_t co
 
        /*
         *      Any expansions have been turned into data.
+        *
+        *      @todo - set of FR_TYPE_GROUP to leaf?
         */
        if (tmpl_is_data(current->rhs.vpt)) {
                rhs_box = tmpl_value(current->rhs.vpt);
@@ -544,7 +547,35 @@ static int apply_edits_to_leaf(request_t *request, edit_map_t *current, map_t co
        }
 
        /*
-        *      Save the VP we're editing.
+        *      Set means "delete ALL matching things, and add new ones".
+        */
+       if (map->op == T_OP_SET) {
+               fr_dict_attr_t const *da = current->lhs.vp->da;
+
+               /*
+                *      Create all of the relevant VPs.
+                *
+                *      @todo - this really just be a dcursor, so that
+                *      the "list of data" case is indistinguishable
+                *      from the "list of vps".  But in order to do
+                *      that, we will need a dcursor which walks over
+                *      VPs, but returns a pointer to the data.  :(
+                */
+               while (vp != NULL) {
+                       fr_pair_t *set;
+
+                       MEM(set = fr_pair_afrom_da(current->lhs.vp_parent, da));
+                       if (fr_value_box_cast(set, &set->data, da->type, da, &vp->data) < 0) return -1;
+                       fr_pair_append(&current->rhs.pair_list, set);
+
+                       vp = fr_dcursor_next(&cursor);
+               }
+
+               goto apply_list;
+       }
+
+       /*
+        *      Save the VP we're doing to edit.
         */
        if (fr_edit_list_save_pair_value(current->el, current->lhs.vp) < 0) {
        fail:
index 3e0b2ccf42af53211f82efc9ef2e51cb9a83b85b..f11cd8d62b3e322dcf51fc2d642fad13999d7d68 100644 (file)
@@ -13,4 +13,19 @@ if (&Tmp-Integer-1 != 27) {
        test_fail
 }
 
+#
+#  We should be able to copy multiple attributes
+#
+&Tmp-Integer-2 := &Tmp-Integer-0[*]
+&Tmp-Integer-1 := 0
+
+
+#
+#  Do operations on sets of inputs.
+#
+&Tmp-Integer-1 += &Tmp-Integer-2[*]
+if (&Tmp-Integer-1 != 27) {
+       test_fail
+}
+
 success