]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
If a tmpl is data, no need to push it for evaluation
authorNick Porter <nick@portercomputing.co.uk>
Tue, 15 Jul 2025 11:34:25 +0000 (12:34 +0100)
committerNick Porter <nick@portercomputing.co.uk>
Tue, 15 Jul 2025 13:15:46 +0000 (14:15 +0100)
src/lib/unlang/call_env.c

index 614a5891fbb9f66ac948d6e1b2a99dfe69e8ff63..31de8f44bdda6081c33462806943e7a6e3bf38ff 100644 (file)
@@ -143,6 +143,7 @@ static unlang_action_t call_env_expand_start(UNUSED unlang_result_t *p_result, r
        call_env_parsed_t const *env = NULL;
        void            **out;
 
+again:
        while ((call_env_rctx->last_expanded = call_env_parsed_next(&call_env_rctx->call_env->parsed, call_env_rctx->last_expanded))) {
                env = call_env_rctx->last_expanded;
                fr_assert(env != NULL);
@@ -232,6 +233,33 @@ static unlang_action_t call_env_expand_start(UNUSED unlang_result_t *p_result, r
                ctx = *out;
        }
 
+       /*
+        *      If the tmpl is already data, we can just copy the data to the right place.
+        */
+       if (tmpl_is_data(call_env_rctx->last_expanded->data.tmpl)) {
+               fr_value_box_t          *vb;
+               call_env_result_t       result;
+               void                    *box_out;
+
+               MEM(vb = fr_value_box_acopy(ctx, &call_env_rctx->last_expanded->data.tmpl->data.literal));
+               fr_value_box_list_insert_tail(&call_env_rctx->tmpl_expanded, vb);
+
+               box_out = ((uint8_t*)(*call_env_rctx->data)) + env->rule->pair.offset;
+
+               if (call_env_multi(env->rule->flags)) {
+                       void *array = *(void **)box_out;
+                       box_out = ((uint8_t *)array) + env->rule->pair.size * env->multi_index;
+               }
+
+               /* coverity[var_deref_model] */
+               result = call_env_result(*call_env_rctx->data, request, box_out, NULL, env, &call_env_rctx->tmpl_expanded);
+               if (result != CALL_ENV_SUCCESS) {
+                       if (call_env_rctx->result) *call_env_rctx->result = result;
+                       return UNLANG_ACTION_FAIL;
+               }
+               goto again;
+       }
+
        if (unlang_tmpl_push(ctx, &call_env_rctx->expansion_result, &call_env_rctx->tmpl_expanded, request,
                             call_env_rctx->last_expanded->data.tmpl,
                             NULL) < 0) return UNLANG_ACTION_FAIL;