]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
clear out old resume function and rctx
authorAlan T. DeKok <aland@freeradius.org>
Tue, 15 Aug 2023 12:26:07 +0000 (08:26 -0400)
committerAlan T. DeKok <aland@freeradius.org>
Tue, 15 Aug 2023 14:02:26 +0000 (10:02 -0400)
when we have two xlats in a row, the first one might need to be
resumed, so it pushes a resume ctx onto the stack.  It then returns
"done", and the xlat evaluator goes to the next xlat node.

However, the next xlat node might _not_ push a resume function onto
the stack.  So when the evaluator resumes, it will see the first
resume function and rctx, and call it again.  Cue boom.

The solution is on DONE, replace the resume function / rctx with
a NULL one which does nothing.

src/lib/unlang/xlat_eval.c
src/tests/keywords/expr-double [new file with mode: 0644]

index cff75c5a632ce20955cca65ee8b56e7ab6e90a5d..379f6fe8360ac6101909d4b09fbf7076a6f39a2f 100644 (file)
@@ -799,6 +799,13 @@ void xlat_signal(xlat_func_signal_t signal, xlat_exp_t const *exp,
        signal(XLAT_CTX(exp->call.inst, t->data, t->mctx, NULL, rctx), request, action);
 }
 
+static xlat_action_t xlat_null_resume(UNUSED TALLOC_CTX *ctx, UNUSED fr_dcursor_t *out,
+                                     UNUSED xlat_ctx_t const *xctx,
+                                     UNUSED request_t *request, UNUSED fr_value_box_list_t *in)
+{
+       return XLAT_ACTION_DONE;
+}
+
 /** Call an xlat's resumption method
  *
  * @param[in] ctx              to allocate value boxes in.
@@ -854,6 +861,8 @@ xlat_action_t xlat_frame_eval_resume(TALLOC_CTX *ctx, fr_dcursor_t *out,
                return xa;
 
        case XLAT_ACTION_DONE:
+               unlang_xlat_yield(request, xlat_null_resume, NULL, 0, NULL);
+
                fr_dcursor_next(out);           /* Wind to the start of this functions output */
                RDEBUG2("| --> %pV", fr_dcursor_current(out));
                if (node->call.func &&
@@ -1196,7 +1205,7 @@ xlat_action_t xlat_frame_eval(TALLOC_CTX *ctx, fr_dcursor_t *out, xlat_exp_head_
                                xlat_exec_rctx_t *rctx;
 
                                /*
-                                *
+                                *      Allocate and initialize the output context, with value-boxes, exec status, etc.
                                 */
                                MEM(rctx = talloc_zero(unlang_interpret_frame_talloc_ctx(request), xlat_exec_rctx_t));
                                fr_value_box_list_init(&rctx->list);
diff --git a/src/tests/keywords/expr-double b/src/tests/keywords/expr-double
new file mode 100644 (file)
index 0000000..da5c94c
--- /dev/null
@@ -0,0 +1 @@
+&Filter-Id := "%{eval:1 + 1} %{tolower: 1}"