]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
Add sanity to foreach - skipping structural attributes
authorNick Porter <nick@portercomputing.co.uk>
Mon, 23 Jan 2023 15:35:04 +0000 (15:35 +0000)
committerArran Cudbard-Bell <a.cudbardb@freeradius.org>
Thu, 9 Feb 2023 16:58:11 +0000 (10:58 -0600)
Allows for

  foreach &request.[*] { ... }

to process safely

src/lib/unlang/foreach.c

index 0f9e6c4f864601745c7b4282ce61b14a4a2d8e29..a4034ee510a51e043a8b652876be3c81f386ad9d 100644 (file)
@@ -83,6 +83,21 @@ static unlang_action_t unlang_foreach_next(rlm_rcode_t *p_result, request_t *req
        if (is_stack_unwinding_to_break(request->stack)) return UNLANG_ACTION_CALCULATE_RESULT;
 
        vp = fr_dcursor_next(&state->cursor);
+
+       /*
+        *      Skip any non-leaf attributes - adds sanity to foreach &request.[*]
+        */
+       while (vp) {
+               switch (vp->da->type) {
+               case FR_TYPE_LEAF:
+                       break;
+               default:
+                       vp = fr_dcursor_next(&state->cursor);
+                       continue;
+               }
+               break;
+       }
+
        if (!vp) {
                *p_result = frame->result;
 #ifndef NDEBUG
@@ -118,6 +133,7 @@ static unlang_action_t unlang_foreach(rlm_rcode_t *p_result, request_t *request,
 
        int                             i, depth = 0;
        fr_pair_list_t                  vps;
+       fr_pair_t                       *vp;
 
        fr_pair_list_init(&vps);
 
@@ -157,10 +173,36 @@ static unlang_action_t unlang_foreach(rlm_rcode_t *p_result, request_t *request,
 
        fr_assert(!fr_pair_list_empty(&vps));
 
-       state->request = request;
-       state->depth = depth;
        fr_pair_list_append(&state->vps, &vps);
        fr_pair_dcursor_init(&state->cursor, &state->vps);
+
+       /*
+        *      Skip any non-leaf attributes at the start of the cursor
+        *      Adds sanity to foreach &request.[*]
+        */
+       vp = fr_dcursor_current(&state->cursor);
+       while (vp) {
+               switch (vp->da->type) {
+               case FR_TYPE_LEAF:
+                       break;
+               default:
+                       vp = fr_dcursor_next(&state->cursor);
+                       continue;
+               }
+               break;
+       }
+
+       /*
+        *      If no non-leaf attributes found clean up
+        */
+       if (!vp) {
+               fr_dcursor_free_list(&state->cursor);
+               *p_result = RLM_MODULE_NOOP;
+               return UNLANG_ACTION_CALCULATE_RESULT;
+       }
+
+       state->request = request;
+       state->depth = depth;
 #ifndef NDEBUG
        state->indent = request->log.unlang_indent;
 #endif