]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
v4: Define arguments for %(length: ) xlat (#4037)
authorNick Porter <nick@portercomputing.co.uk>
Mon, 29 Mar 2021 14:22:01 +0000 (15:22 +0100)
committerGitHub <noreply@github.com>
Mon, 29 Mar 2021 14:22:01 +0000 (15:22 +0100)
* Define arguments for %(length: ) xlat

* Update tests that use %(length: ) xlat

* Update docs for %(length: ) xlat

* Make xlat_fmt_aprint() reflect original call syntax

* Make xlat_print reflect original call syntax

doc/antora/modules/reference/pages/xlat/builtin.adoc
src/lib/unlang/xlat_builtin.c
src/lib/unlang/xlat_eval.c
src/lib/unlang/xlat_tokenize.c
src/tests/keywords/escape-sequences
src/tests/keywords/length
src/tests/keywords/randstr
src/tests/keywords/truncation
src/tests/keywords/xlat-sub
src/tests/modules/cache_rbtree/cache-bin.unlang
src/tests/unit/xlat/base.txt

index 3f25ea83644b50fbd305bb50442bd8abd30afd94..f4912202b96b2e2418020ef4778452077cf61a6f 100644 (file)
@@ -6,7 +6,7 @@ which operate on inputs, and produce an output.
 
 == Attribute Manipulation
 
-=== %{length: ... }
+=== %(length: ... )
 
 The `length` expansion returns the size of the input as an integer.
 When the input is a string, then the output is identical to the
@@ -27,8 +27,8 @@ update control {
 }
 
 update reply {
-    &Reply-Message := "The length of %{control.Tmp-String-0} is %{length:&control.Tmp-String-0}"
-    &Reply-Message += "The length of %{control.Framed-IP-Address} is %{length:&control.Framed-IP-Address}"
+    &Reply-Message := "The length of %{control.Tmp-String-0} is %(length:&control.Tmp-String-0)"
+    &Reply-Message += "The length of %{control.Framed-IP-Address} is %(length:&control.Framed-IP-Address)"
 }
 ----
 
index 356b7f1302ce0ca2e8c379289274d3f9c1019012..ffe64276e03dd2a96075403e898af192bed173b5 100644 (file)
@@ -1870,12 +1870,17 @@ static xlat_action_t xlat_func_join(UNUSED TALLOC_CTX *ctx, fr_dcursor_t *out,
        return XLAT_ACTION_DONE;
 }
 
+static xlat_arg_parser_t const xlat_func_length_args[] = {
+       { .single = true, .variadic = true, .type = FR_TYPE_VOID },
+       XLAT_ARG_PARSER_TERMINATOR
+};
+
 /** Return the on-the-wire size of the boxes in bytes
  *
  * Example:
 @verbatim
-"%{length:foobar}" == 6
-"%{length:%{bin:0102030005060708}}" == 8
+"%(length:foobar)" == 6
+"%(length:%{bin:0102030005060708})" == 8
 @endverbatim
  *
  * @see #xlat_func_strlen
@@ -1887,12 +1892,9 @@ static xlat_action_t xlat_func_length(TALLOC_CTX *ctx, fr_dcursor_t *out,
                                      UNUSED void *xlat_thread_inst, fr_value_box_list_t *in)
 
 {
-       fr_value_box_t  *vb;
-       fr_dcursor_t    cursor;
+       fr_value_box_t  *vb = NULL;
 
-       for (vb = fr_dcursor_talloc_init(&cursor, in, fr_value_box_t);
-            vb;
-            vb = fr_dcursor_next(&cursor)) {
+       while ((vb = fr_dlist_next(in, vb))) {
                fr_value_box_t *my;
 
                MEM(my = fr_value_box_alloc(ctx, FR_TYPE_SIZE, NULL, false));
@@ -3103,6 +3105,7 @@ do { \
        XLAT_REGISTER_ARGS("hmacsha1", xlat_func_hmac_sha1, xlat_hmac_args);
        XLAT_REGISTER_ARGS("integer", xlat_func_integer, xlat_func_integer_args);
        XLAT_REGISTER_ARGS("join", xlat_func_join, xlat_func_join_args);
+       XLAT_REGISTER_ARGS("length", xlat_func_length, xlat_func_length_args);
        XLAT_REGISTER_ARGS("nexttime", xlat_func_next_time, xlat_func_next_time_args);
        XLAT_REGISTER_ARGS("pairs", xlat_func_pairs, xlat_func_pairs_args);
        XLAT_REGISTER_ARGS("lpad", xlat_func_lpad, xlat_func_pad_args);
@@ -3119,7 +3122,6 @@ do { \
        XLAT_REGISTER_MONO("base64decode", xlat_func_base64_decode, xlat_func_base64_decode_arg);
        XLAT_REGISTER_MONO("bin", xlat_func_bin, xlat_func_bin_arg);
        XLAT_REGISTER_MONO("hex", xlat_func_hex, xlat_func_hex_arg);
-       xlat_register(NULL, "length", xlat_func_length, false);
        XLAT_REGISTER_MONO("map", xlat_func_map, xlat_func_map_arg);
        XLAT_REGISTER_MONO("md4", xlat_func_md4, xlat_func_md4_arg);
        XLAT_REGISTER_MONO("md5", xlat_func_md5, xlat_func_md5_arg);
index fc8771649a1fb38dddb752d8bac2c2f7103d42c2..7945478f9d9dd6287a2c9ed9d291d266ebce69ba 100644 (file)
@@ -123,29 +123,43 @@ static char *xlat_fmt_aprint(TALLOC_CTX *ctx, xlat_exp_t const *node)
                xlat_exp_t const        *child = node->child;
                char                    *out, *n_out;
                TALLOC_CTX              *pool;
+               char                    open = '{', close = '}';
+               bool                    first_done = false;
 
-               if (!child) return talloc_asprintf(ctx, "%%{%s:}", node->call.func->name);
+               if (node->call.func->input_type == XLAT_INPUT_ARGS) {
+                       open = '(';
+                       close = ')';
+               }
+               if (!child) return talloc_asprintf(ctx, "%%%c%s:%c", open, node->call.func->name, close);
 
-               out = talloc_asprintf(ctx, "%%{%s:", node->call.func->name);
+               out = talloc_asprintf(ctx, "%%%c%s:", open, node->call.func->name);
                pool = talloc_pool(NULL, 128);  /* Size of a single child (probably ok...) */
                do {
                        char *child_str;
 
                        child_str = xlat_fmt_aprint(pool, child);
                        if (child_str) {
-                               n_out = talloc_buffer_append_buffer(ctx, out, child_str);
-                               if (!n_out) {
-                                       talloc_free(out);
-                                       talloc_free(pool);
-                                       return NULL;
+                               if ((first_done) && (node->call.func->input_type == XLAT_INPUT_ARGS)) {
+                                       n_out = talloc_strdup_append_buffer(out, " ");
+                                       if (!n_out) {
+                                       child_error:
+                                               talloc_free(out);
+                                               talloc_free(pool);
+                                               return NULL;
+                                       }
+                                       out = n_out;
                                }
+
+                               n_out = talloc_buffer_append_buffer(ctx, out, child_str);
+                               if (!n_out) goto child_error;
                                out = n_out;
+                               first_done = true;
                        }
                        talloc_free_children(pool);     /* Clear pool contents */
                } while ((child = child->next));
                talloc_free(pool);
 
-               n_out = talloc_strdup_append_buffer(out, "}");
+               n_out = talloc_strndup_append_buffer(out, &close, 1);
                if (!n_out) {
                        talloc_free(out);
                        return NULL;
index 483145a2840e455498301cb31283608b0c8adf01..923723816431275018e3b9d688b3db62b2f70ab5 100644 (file)
@@ -1174,6 +1174,7 @@ ssize_t xlat_print(fr_sbuff_t *out, xlat_exp_t const *head, fr_sbuff_escape_rule
        ssize_t                 slen;
        size_t                  at_in = fr_sbuff_used_total(out);
        xlat_exp_t const        *node = head;
+       char                    close;
 
        if (!node) return 0;
 
@@ -1198,7 +1199,13 @@ ssize_t xlat_print(fr_sbuff_t *out, xlat_exp_t const *head, fr_sbuff_escape_rule
                        break;
                }
 
-               FR_SBUFF_IN_STRCPY_LITERAL_RETURN(out, "%{");
+               if ((node->type == XLAT_FUNC) && (node->call.func->input_type == XLAT_INPUT_ARGS)) {
+                       FR_SBUFF_IN_STRCPY_LITERAL_RETURN(out, "%(");
+                       close = ')';
+               } else {
+                       FR_SBUFF_IN_STRCPY_LITERAL_RETURN(out, "%{");
+                       close = '}';
+               }
                switch (node->type) {
                case XLAT_ATTRIBUTE:
                        slen = tmpl_attr_print(out, node->attr, TMPL_ATTR_REF_PREFIX_NO);
@@ -1259,7 +1266,7 @@ ssize_t xlat_print(fr_sbuff_t *out, xlat_exp_t const *head, fr_sbuff_escape_rule
                        fr_assert_fail(NULL);
                        break;
                }
-               FR_SBUFF_IN_CHAR_RETURN(out, '}');
+               FR_SBUFF_IN_CHAR_RETURN(out, close);
        next:
                node = node->next;
        }
index 6a73bc30e9d72450f7dd7c9f6b7002aee97ad5c4..ffb8a0e7f4ce18992f2f4c656e470020251375db 100644 (file)
@@ -17,11 +17,11 @@ update request {
 }
 
 
-if ("%{length:%{Tmp-String-0}}" != 39) {
+if ("%(length:%{Tmp-String-0})" != 39) {
        test_fail
 }
 
-if ("%{length:%{Tmp-String-1}}" != 42) {
+if ("%(length:%{Tmp-String-1})" != 42) {
        test_fail
 }
 
index b3570c7420359d48ae4d63c861ef0888abc991f1..157c2de0a07402aa96e523b2d8db47fd328efc29 100644 (file)
@@ -21,7 +21,7 @@ abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz'
 }
 
 update request {
-       &Tmp-Integer-0        := "%{length:%{Tmp-String-0}}"
+       &Tmp-Integer-0        := "%(length:%{Tmp-String-0})"
 }
 
 if (&Tmp-Integer-0 != 260) {
@@ -29,14 +29,14 @@ if (&Tmp-Integer-0 != 260) {
 }
 
 update request {
-       &Tmp-Integer-0        := "%{length:%{Tmp-String-2}}"
-       &Tmp-Integer-1        := "%{length:%{Tmp-Octets-0}}"
-       &Tmp-Integer-2        := "%{length:%{Tmp-IP-Address-0}}"
-       &Tmp-Integer-4        := "%{length:%{Tmp-Integer-0}}"
-       &Tmp-Integer-6        := "%{length:%{Tmp-Cast-Ifid}}"
-       &Tmp-Integer-7        := "%{length:%{Tmp-Cast-IPv6Addr}}"
-       &Tmp-Integer-8        := "%{length:%{Tmp-Cast-IPv6Prefix}}"
-       &Tmp-Integer-9        := "%{length:%{Tmp-Cast-Byte}}"
+       &Tmp-Integer-0        := "%(length:%{Tmp-String-2})"
+       &Tmp-Integer-1        := "%(length:%{Tmp-Octets-0})"
+       &Tmp-Integer-2        := "%(length:%{Tmp-IP-Address-0})"
+       &Tmp-Integer-4        := "%(length:%{Tmp-Integer-0})"
+       &Tmp-Integer-6        := "%(length:%{Tmp-Cast-Ifid})"
+       &Tmp-Integer-7        := "%(length:%{Tmp-Cast-IPv6Addr})"
+       &Tmp-Integer-8        := "%(length:%{Tmp-Cast-IPv6Prefix})"
+       &Tmp-Integer-9        := "%(length:%{Tmp-Cast-Byte})"
 }
 
 # String - bin 0x39383730
@@ -81,10 +81,10 @@ if (&Tmp-Integer-9 != 1) {
 }
 
 update request {
-       &Tmp-Integer-0        := "%{length:%{Tmp-Cast-Short}}"
-       &Tmp-Integer-1        := "%{length:%{Tmp-Cast-Ether}}"
-       &Tmp-Integer-2        := "%{length:%{Tmp-Cast-Integer64}}"
-       &Tmp-Integer-3        := "%{length:%{Tmp-Cast-IPv4Prefix}}"
+       &Tmp-Integer-0        := "%(length:%{Tmp-Cast-Short})"
+       &Tmp-Integer-1        := "%(length:%{Tmp-Cast-Ether})"
+       &Tmp-Integer-2        := "%(length:%{Tmp-Cast-Integer64})"
+       &Tmp-Integer-3        := "%(length:%{Tmp-Cast-IPv4Prefix})"
 }
 
 # short - bin 0x373b
index 175b72652b626c9729fac43f7de4be2845800ef1..090bb15d819506e425ce6f2d7403dafbaca0610e 100644 (file)
@@ -42,7 +42,7 @@ if (&Tmp-String-4 != "") {
 #
 #  Check repetition of binary output
 #
-if ("%{length:%{Tmp-String-5}}" != 10) {
+if ("%(length:%{Tmp-String-5})" != 10) {
        test_fail
 }
 
index bdcff618b08804a05a13a0f93cb4c64501238311..45b58528150813a510224551e14b3d3e93a34c93 100644 (file)
@@ -76,7 +76,7 @@ a02f4a3ab98d75992d68a15d393387fe9ef01041569570ad6fe884764e55567311bcacfcffae7655
 
 # Actual length of octet string is 4083 bytes
 update request {
-       &Tmp-Integer-0 := "%{length:%{Tmp-Octets-0}}"
+       &Tmp-Integer-0 := "%(length:%{Tmp-Octets-0})"
 }
 
 if (&Tmp-Integer-0 != 4083) {
@@ -92,7 +92,7 @@ update request {
        &Tmp-String-0 := "%{1}"
 }
 
-if ("%{length:%{Tmp-String-0}}" != 8166) {
+if ("%(length:%{Tmp-String-0})" != 8166) {
        test_fail
 }
 
index 61a9e32574594dfcd924a6ea37fbac0a3139924f..5b8db068d04b1483b9ed3ab87d77145c440c780a 100644 (file)
@@ -82,7 +82,7 @@ if ("%(sub:%{Tmp-String-0} /z/ b)" != 'aaa') {
 #
 
 # Check that newlines really are newlines
-if ("%{length:%{Tmp-String-1}}" != 3) {
+if ("%(length:%{Tmp-String-1})" != 3) {
        test_fail
 }
 
index abe5d3eb00722defea10756b2984ee1d90fb6428..9136bacf8e14ac8d0b9549168c82169afa385362 100644 (file)
@@ -60,7 +60,7 @@ else {
        test_fail
 }
 
-if ("%{length:%{Tmp-String-1}}" == 11) {
+if ("%(length:%{Tmp-String-1})" == 11) {
        test_pass
 }
 else {
@@ -91,7 +91,7 @@ else {
        test_fail
 }
 
-if ("%{length:%{Tmp-String-1}}" == 7) {
+if ("%(length:%{Tmp-String-1})" == 7) {
        test_pass
 }
 else {
@@ -159,7 +159,7 @@ else {
        test_fail
 }
 
-if ("%{length:%{Tmp-String-1}}" == 11) {
+if ("%(length:%{Tmp-String-1})" == 11) {
        test_pass
 }
 else {
@@ -190,7 +190,7 @@ else {
        test_fail
 }
 
-if ("%{length:%{Tmp-String-1}}" == 7) {
+if ("%(length:%{Tmp-String-1})" == 7) {
        test_pass
 }
 else {
index 9fc7358d89873c27ad49b5652927d7be5a2f8417..bb2b790b78b8038a84688222604bbd548c183342 100644 (file)
@@ -132,13 +132,13 @@ match \"%{reply.Vendor-Specific.3GPP.IMSI[2]}\"
 xlat /([A-Z0-9\\-]*)_%{Calling-Station-Id}/
 match /([A-Z0-9\\-]*)_%{Calling-Station-Id}/
 
-xlat %{length}
-match %{length}
+xlat %(length:)
+match %(length:)
 
-xlat %{length:
+xlat %(length:
 match ERROR offset 9: Missing closing brace
 
-xlat %{length:1 + 2
+xlat %(length:1 + 2
 match ERROR offset 14: Missing closing brace
 
 xlat \"%t\tfoo\"