]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
v4: Convert %(interpreter: ) to new xlat api (#4036)
authorNick Porter <nick@portercomputing.co.uk>
Mon, 29 Mar 2021 14:19:25 +0000 (15:19 +0100)
committerGitHub <noreply@github.com>
Mon, 29 Mar 2021 14:19:25 +0000 (15:19 +0100)
* Convert %(interpreter: ) to new xlat api

* Update existing tests to use new %(interpreter: ) syntax

* Update documentation for %(interpreter: ) xlat

* Add test for %(interpreter: ) xlat

* Typo

Co-authored-by: Arran Cudbard-Bell <a.cudbardb@freeradius.org>
doc/antora/modules/reference/pages/xlat/builtin.adoc
src/lib/unlang/interpret.c
src/tests/keywords/policy.conf
src/tests/keywords/xlat-interpreter [new file with mode: 0644]
src/tests/modules/unit_test_module.conf

index 38bdac403e49dc1a0c9c1edaccd6aabc901a6aae..3f25ea83644b50fbd305bb50442bd8abd30afd94 100644 (file)
@@ -280,7 +280,7 @@ recv Access-Request {
 ...
 ```
 
-=== %{interpreter:<state>}
+=== %(interpreter:<state>)
 
 Get information about the interpreter state.
 
@@ -300,7 +300,7 @@ Get information about the interpreter state.
 
 [source,unlang]
 ----
-"Failure in test at line %{interpreter:...filename}:%{interpreter:...line}"
+"Failure in test at line %(interpreter:...filename):%(interpreter:...line)"
 ----
 
 .Output
index 3b57724ae4032b122f228fa94bb93188abbde70d..9a3d0b73a2031201e88732c93222607ad6aa9acb 100644 (file)
@@ -1238,27 +1238,39 @@ TALLOC_CTX *unlang_interpret_frame_talloc_ctx(request_t *request)
        return (TALLOC_CTX *) request;
 }
 
+static xlat_arg_parser_t const unlang_interpret_xlat_args[] = {
+       { .required = true, .single = true, .type = FR_TYPE_STRING },
+       XLAT_ARG_PARSER_TERMINATOR
+};
+
 /** Get information about the interpreter state
  *
  * @ingroup xlat_functions
  */
-static ssize_t unlang_interpret_xlat(UNUSED TALLOC_CTX *ctx, char **out, size_t outlen,
-                                    UNUSED void const *mod_inst, UNUSED void const *xlat_inst,
-                                    request_t *request, char const *fmt)
+static xlat_action_t unlang_interpret_xlat(UNUSED TALLOC_CTX *ctx, fr_dcursor_t *out, request_t *request,
+                                          UNUSED void const *xlat_inst, UNUSED void *xlat_thread_inst,
+                                          fr_value_box_list_t *in)
 {
        unlang_stack_t          *stack = request->stack;
        int                     depth = stack->depth;
        unlang_stack_frame_t    *frame;
        unlang_t const          *instruction;
+       fr_value_box_t          *arg = fr_dlist_head(in);
+       char const              *fmt = arg->vb_strvalue;
+       fr_value_box_t          *vb;
 
-       fr_skip_whitespace(fmt);
-
+       MEM(vb = fr_value_box_alloc_null(ctx));
        /*
         *      Find the correct stack frame.
         */
        while (*fmt == '.') {
                if (depth <= 1) {
-                       return snprintf(*out, outlen, "<underflow>");
+                       if (fr_value_box_bstrndup(ctx, vb, NULL, "<underflow>", 11, false) < 0) {
+                       error:
+                               talloc_free(vb);
+                               return XLAT_ACTION_FAIL;
+                       };
+                       goto finish;
                }
 
                fmt++;
@@ -1275,29 +1287,33 @@ static ssize_t unlang_interpret_xlat(UNUSED TALLOC_CTX *ctx, char **out, size_t
         *      Nothing there...
         */
        if (!instruction) {
-               **out = '\0';
-               return 0;
+               return XLAT_ACTION_DONE;
        }
 
        /*
         *      Name of the instruction.
         */
        if (strcmp(fmt, "name") == 0) {
-               return snprintf(*out, outlen, "%s", instruction->name);
+               if (fr_value_box_bstrndup(ctx, vb, NULL, instruction->name,
+                                         strlen(instruction->name), false) < 0) goto error;
+               goto finish;
        }
 
        /*
         *      Unlang type.
         */
        if (strcmp(fmt, "type") == 0) {
-               return snprintf(*out, outlen, "%s", unlang_ops[instruction->type].name);
+               if (fr_value_box_bstrndup(ctx, vb, NULL, unlang_ops[instruction->type].name,
+                                         strlen(unlang_ops[instruction->type].name), false) < 0) goto error;
+               goto finish;
        }
 
        /*
         *      How deep the current stack is.
         */
        if (strcmp(fmt, "depth") == 0) {
-               return snprintf(*out, outlen, "%d", depth);
+               fr_value_box_int32(vb, NULL, depth, false);
+               goto finish;
        }
 
        /*
@@ -1307,13 +1323,15 @@ static ssize_t unlang_interpret_xlat(UNUSED TALLOC_CTX *ctx, char **out, size_t
                unlang_group_t const *g;
 
                if (!unlang_ops[instruction->type].debug_braces) {
-                       return snprintf(*out, outlen, "???");
+                       if (fr_value_box_bstrndup(ctx, vb, NULL, "???", 3, false) < 0) goto error;
+                       goto finish;
                }
 
                g = (unlang_group_t const *) instruction;
                fr_assert(g->cs != NULL);
 
-               return snprintf(*out, outlen, "%d", cf_lineno(g->cs));
+               fr_value_box_int32(vb, NULL, cf_lineno(g->cs), false);
+               goto finish;
        }
 
        /*
@@ -1323,20 +1341,26 @@ static ssize_t unlang_interpret_xlat(UNUSED TALLOC_CTX *ctx, char **out, size_t
                unlang_group_t const *g;
 
                if (!unlang_ops[instruction->type].debug_braces) {
-                       return snprintf(*out, outlen, "???");
+                       if (fr_value_box_bstrndup(ctx, vb, NULL, "???", 3, false) < 0) goto error;
+                       goto finish;
                }
 
                g = (unlang_group_t const *) instruction;
                fr_assert(g->cs != NULL);
 
-               return snprintf(*out, outlen, "%s", cf_filename(g->cs));
+               if (fr_value_box_bstrndup(ctx, vb, NULL, cf_filename(g->cs),
+                                         strlen(cf_filename(g->cs)), false) < 0) goto error;
+               goto finish;
        }
 
-       **out = '\0';
-       return 0;
+finish:
+       if (vb->type != FR_TYPE_NULL) fr_dcursor_append(out, vb);
+       return XLAT_ACTION_DONE;
 }
 
 void unlang_interpret_init_global(void)
 {
-       (void) xlat_register_legacy(NULL, "interpreter", unlang_interpret_xlat, NULL, NULL, 0, XLAT_DEFAULT_BUF_LEN);
+       xlat_t  *xlat;
+       xlat = xlat_register(NULL, "interpreter", unlang_interpret_xlat, false);
+       xlat_func_args(xlat, unlang_interpret_xlat_args);
 }
index 9f19b1e6e67899fc9e1565eb9e3aca155aa5e03c..57b0f6e7b99e0ca8296cfeecbf06fe0854e4ebed 100644 (file)
@@ -68,12 +68,12 @@ success {
 
 test_fail {
        update reply {
-               &Result-Status += "Failure in test at line %{interpreter:...line}"
+               &Result-Status += "Failure in test at line %(interpreter:...line)"
        }
 
        if (&parent.request.User-Name) {
                update parent.reply {
-                       &Result-Status += "Failure in test at line %{interpreter:...line}"
+                       &Result-Status += "Failure in test at line %(interpreter:...line)"
                }
        }
 }
diff --git a/src/tests/keywords/xlat-interpreter b/src/tests/keywords/xlat-interpreter
new file mode 100644 (file)
index 0000000..d43977c
--- /dev/null
@@ -0,0 +1,31 @@
+#
+#  PRE: update if
+#
+#  Note the test for %(interpreter:.line) is sensitive to the position of the
+#  "update request" line in the file
+#
+
+update request {
+        &Tmp-String-0 := "%(interpreter:.filename)"
+        &Tmp-Integer-0 := "%(interpreter:.line)"
+        &Tmp-String-1 := "%(interpreter:.name)"
+        &Tmp-String-2 := "%(interpreter:.type)"
+}
+
+if (&Tmp-String-0 != "src/tests/keywords/xlat-interpreter") {
+        test_fail
+}
+
+if (&Tmp-String-1 != "request") {
+        test_fail
+}
+
+if (&Tmp-String-2 != "update") {
+        test_fail
+}
+
+if (&Tmp-Integer-0 != 8) {
+        test_fail
+}
+
+success
index 410a1ab1c28c464fbf9f1af8c40250e8f3a0a5b1..c28649e1e7e05f58215bffa30b0d755206878d50 100644 (file)
@@ -55,7 +55,7 @@ policy {
 
        test_fail {
                update reply {
-                       &Reply-Message += "Failure in test at line %{interpreter:...line}"
+                       &Reply-Message += "Failure in test at line %(interpreter:...line)"
                }
                reject
        }