From: Alan T. DeKok Date: Mon, 21 Aug 2023 21:58:41 +0000 (-0400) Subject: += also means "create if it doesn't exist" X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c7676a8974c74b2f30fd265027718bd72aee416d;p=thirdparty%2Ffreeradius-server.git += also means "create if it doesn't exist" at least for operations where "+=" is meaningful We probably want to do something similar for union, merge, etc. if the LHS doesn't exist. --- diff --git a/src/lib/unlang/edit.c b/src/lib/unlang/edit.c index 7aee07d0d43..c4c5e48407f 100644 --- a/src/lib/unlang/edit.c +++ b/src/lib/unlang/edit.c @@ -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 index 00000000000..a0e68d85d9e --- /dev/null +++ b/src/tests/keywords/edit-add-create @@ -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 diff --git a/src/tests/keywords/edit-group b/src/tests/keywords/edit-group index 1e17bdf1a4b..3e11f4bd39a 100644 --- a/src/tests/keywords/edit-group +++ b/src/tests/keywords/edit-group @@ -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" }