]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
remove local variables back to front
authorAlan T. DeKok <aland@freeradius.org>
Wed, 19 Mar 2025 04:31:37 +0000 (11:31 +0700)
committerAlan T. DeKok <aland@freeradius.org>
Wed, 19 Mar 2025 04:31:37 +0000 (11:31 +0700)
and update tests, which now pass

src/lib/unlang/foreach.c
src/lib/unlang/interpret.c
src/tests/keywords/foreach-nested

index 86992856b6a9c4ef442806efec61562a2b4f68c6..ce300c40512169d0a190ed4b2dd4e8bffd007354 100644 (file)
@@ -557,6 +557,8 @@ static unlang_action_t unlang_foreach(rlm_rcode_t *p_result, request_t *request,
        if (gext->value) {
                state->vpt = gext->vpt;
 
+               fr_assert(fr_pair_find_by_da(&request->local_pairs, NULL, gext->value) == NULL);
+
                /*
                 *      Create the local variable and populate its value.
                 */
@@ -568,6 +570,8 @@ static unlang_action_t unlang_foreach(rlm_rcode_t *p_result, request_t *request,
                fr_assert(state->value != NULL);
 
                if (gext->key) {
+                       fr_assert(fr_pair_find_by_da(&request->local_pairs, NULL, gext->key) == NULL);
+
                        if (fr_pair_append_by_da(request->local_ctx, &state->key, &request->local_pairs, gext->key) < 0) {
                                REDEBUG("Failed creating %s", gext->key->name);
                                *p_result = RLM_MODULE_FAIL;
index 0e5e34d738fb2193ff215c181e5cc3ef4294c693..9d15001d6e5f853fe971bfa6b7907c171e700185 100644 (file)
@@ -219,10 +219,21 @@ typedef struct {
 
 static int _local_variables_free(unlang_variable_ref_t *ref)
 {
-       fr_pair_list_foreach(&ref->request->local_pairs, vp) {
-               if (vp->da->dict != ref->dict) break;
+       fr_pair_t *vp, *prev;
+
+       /*
+        *      Local variables are appended to the end of the list.  So we remove them by walking backwards
+        *      from the end of the list.
+        */
+       vp = fr_pair_list_tail(&ref->request->local_pairs);
+       while (vp) {
+               prev = fr_pair_list_prev(&ref->request->local_pairs, vp);
+               if (vp->da->dict != ref->dict) {
+                       break;
+               }
 
                (void) fr_pair_delete(&ref->request->local_pairs, vp);
+               vp = prev;
        }
 
        return 0;
index 4fc6df014e8c8501370384d44962736698efef38..5f0cb55b7b4daa621ccdff66e86ae28caa0e60a9 100644 (file)
@@ -1,9 +1,9 @@
 # PRE: foreach
 #
-foreach Filter-Id {
-       foreach Calling-Station-Id {
+foreach thing1 (Filter-Id[*]) {
+       foreach thing2 (Calling-Station-Id[*]) {
                reply += {
-                       Called-Station-Id = "%{Foreach-Variable-0} %{Foreach-Variable-1}"
+                       Called-Station-Id = "%{thing1} %{thing2}"
                }
        }
 }