]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
+= also means "create if it doesn't exist"
authorAlan T. DeKok <aland@freeradius.org>
Mon, 21 Aug 2023 21:58:41 +0000 (17:58 -0400)
committerAlan T. DeKok <aland@freeradius.org>
Mon, 21 Aug 2023 21:58:41 +0000 (17:58 -0400)
at least for operations where "+=" is meaningful

We probably want to do something similar for union, merge, etc.
if the LHS doesn't exist.

src/lib/unlang/edit.c
src/tests/keywords/edit-add-create [new file with mode: 0644]
src/tests/keywords/edit-group

index 7aee07d0d431d62fc5abd8e60bd8b1844530689c..c4c5e48407fc8dff5132ddca2015b0cb6b3070e3 100644 (file)
@@ -1243,7 +1243,7 @@ static int check_lhs(request_t *request, unlang_frame_state_edit_t *state, edit_
        current->lhs.create = false;
        current->lhs.vp = NULL;
 
-       DEBUG("%s map %s %s ...", __FUNCTION__, map->lhs->name, fr_tokens[map->op]);
+       DEBUG3("%s map %s %s ...", __FUNCTION__, map->lhs->name, fr_tokens[map->op]);
 
        /*
         *      Create the attribute, including any necessary parents.
@@ -1281,6 +1281,29 @@ static int check_lhs(request_t *request, unlang_frame_state_edit_t *state, edit_
                        RWDEBUG("Cannot set one entry to multiple values for %s", current->lhs.vpt->name);
                        return -1;
                }
+
+       } else if (map->op == T_OP_ADD_EQ) {
+               /*
+                *      For "+=", if there's no existing attribute, create one, and rewrite the operator we
+                *      apply to ":=".  Which also means moving the operator be in edit_map_t, and then updating the
+                *      "apply" funtions above to use that for the operations, but map->op for printing.
+                *
+                *      This allows "foo += 4" to set "foo := 4" when the attribute doesn't exist.  It also allows us
+                *      to do list appending to an empty list.  But likely only for strings, octets, and numbers.
+                *      Nothing much else makes sense.
+                */
+
+               switch (tmpl_attr_tail_da(current->lhs.vpt)->type) {
+               case FR_TYPE_NUMERIC:
+               case FR_TYPE_OCTETS:
+               case FR_TYPE_STRING:
+               case FR_TYPE_STRUCTURAL:
+                       current->lhs.create = true;
+                       break;
+
+               default:
+                       break;
+               }
        }
 
        /*
diff --git a/src/tests/keywords/edit-add-create b/src/tests/keywords/edit-add-create
new file mode 100644 (file)
index 0000000..a0e68d8
--- /dev/null
@@ -0,0 +1,28 @@
+#
+#  Add to something which doesn't exist
+#
+
+&Tmp-Integer-0 += 4
+if !(&Tmp-Integer-0 == 4) {
+       test_fail
+}
+
+
+&Tmp-String-0 += "bar"
+if !(&Tmp-String-0 == "bar") {
+       test_fail
+}
+
+&Tmp-Group-0 += {
+       &Filter-Id = "foo"
+}
+
+if !&Tmp-Group-0 {
+       test_fail
+}
+
+if !(&Tmp-Group-0.Filter-Id == "foo") {
+       test_fail
+}
+
+success
index 1e17bdf1a4b41e03ad99db10bad29bf5bf365db6..3e11f4bd39a23dc9956d4d4e061fca8bec7fb501 100644 (file)
@@ -8,7 +8,7 @@
 #
 group {
        &Tmp-String-0 := "foo"
-       &Tmp-String-1 += "bar" # fails, no existing Tmp-String-1
+       &Tmp-String-1 <<= "bar" # fails, no existing Tmp-String-1
        &Tmp-String-2 := "bar"
 }