]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
xlat: Make %{pack:} work on boxes not attribute references
authorArran Cudbard-Bell <a.cudbardb@freeradius.org>
Thu, 21 May 2020 14:47:38 +0000 (09:47 -0500)
committerArran Cudbard-Bell <a.cudbardb@freeradius.org>
Thu, 21 May 2020 14:47:38 +0000 (09:47 -0500)
doc/antora/modules/unlang/pages/xlat/builtin.adoc
src/lib/unlang/xlat_builtin.c

index 2c1f561bfeb98fc187614204614c9a926152fc4a..4d86133f56ca625e63a156c67ceeee13b48eb277 100644 (file)
@@ -889,11 +889,12 @@ update reply {
 You should wait for 2520s
 ```
 
-=== +%{pack: &Attribute-Name &Attribute-Name ...}+
+=== +%{pack:%{Attribute-Name}%{Attribute-Name}...}+
 
-Pack multiple multiple attributes into a binary string.  For best
-results, each attribute passed to `pack` should be fixed size.  That
-is, not data type `octets` or `string`.
+Pack multiple multiple attributes and/or literals into a binary string.
+For best results, each attribute passed to `pack` should be fixed size.
+That is, not data type `octets` or `string` as the length of those values
+will not be encoded.
 
 See also the `unpack` module, which is the inverse to `pack`.
 
@@ -904,7 +905,7 @@ See also the `unpack` module, which is the inverse to `pack`.
 [source,unlang]
 ----
 update reply {
-    &Class := "%{pack:&reply:Framed-IP-Address &NAS-IP-Address}"
+    &Class := "%{pack:%{reply:Framed-IP-Address}%{NAS-IP-Address}}"
 }
 ----
 
index 9399446b5c63e0ad1139ae19384dec6a18566b74..6d4250069d125f0b8787bebb5ca28de444aabc7b 100644 (file)
@@ -2082,7 +2082,7 @@ static xlat_action_t xlat_func_md5(TALLOC_CTX *ctx, fr_cursor_t *out,
 
 /** Prints the name of the current module processing the request
  *
- * For example will expand to "echo" (not "exec") in 
+ * For example will expand to "echo" (not "exec") in
 @verbatim
 exec echo {
   ...
@@ -2126,7 +2126,7 @@ static xlat_action_t xlat_func_module(TALLOC_CTX *ctx, fr_cursor_t *out,
  *
  * Example:
 @verbatim
-"%{pack:&Attr-Foo &Attr-bar}" == packed hex values of the attributes
+"%{pack:%{Attr-Foo}%{Attr-bar}" == packed hex values of the attributes
 @endverbatim
  *
  * @ingroup xlat_functions
@@ -2135,81 +2135,51 @@ static xlat_action_t xlat_func_pack(TALLOC_CTX *ctx, fr_cursor_t *out,
                                   REQUEST *request, UNUSED void const *xlat_inst, UNUSED void *xlat_thread_inst,
                                   fr_value_box_t **in)
 {
-       fr_value_box_t  *vb;
-       VALUE_PAIR      *vp;
-       fr_cursor_t     *cursor;
-       char            *buffer, *p, *next;
+       fr_value_box_t  *vb, *in_vb;
+       fr_cursor_t     cursor;
 
        if (!*in) {
-               REDEBUG("Missing attribute reference");
+               REDEBUG("Missing input boxes");
                return XLAT_ACTION_FAIL;
        }
 
-       /*
-        *      Concatenate all input into a list of attribute references.
-        */
-       if (fr_value_box_list_concat(ctx, *in, in, FR_TYPE_STRING, true) < 0) {
-               RPEDEBUG("Failed concatenating input");
-               return XLAT_ACTION_FAIL;
-       }
-
-       buffer = talloc_strdup(ctx, (*in)->vb_strvalue);
+       MEM(vb = fr_value_box_alloc(ctx, FR_TYPE_OCTETS, NULL, false));
 
        /*
-        *      Allocate the initial box
+        *      Loop over the input boxes, packing them together.
         */
-       MEM(vb = fr_value_box_alloc(ctx, FR_TYPE_OCTETS, NULL, false));
-       for (p = buffer; p != NULL; p = next) {
-               next = strchr(p, ' ');
-               if (next) {
-                       while (isspace((int) *next)) {
-                               *(next++) = '\0';
-                       }
-               }
-
-               if (xlat_fmt_to_cursor(NULL, &cursor, NULL, request, p) < 0) {
-               fail:
-                       talloc_free(buffer);
-                       talloc_free(vb);
-                       return XLAT_ACTION_FAIL;
-               }
+       for (in_vb = fr_cursor_init(&cursor, in);
+            in_vb;
+            in_vb = fr_cursor_next(&cursor)) {
+               fr_value_box_t *cast, box;
 
-               /*
-                *      Loop over the input attributes, packing them together.
-                */
-               for (vp = fr_cursor_head(cursor);
-                    vp;
-                    vp = fr_cursor_next(cursor)) {
-                       fr_value_box_t *cast, box;
-
-                       if (vp->da->type != FR_TYPE_OCTETS) {
-                               if (fr_value_box_cast(ctx, &box, FR_TYPE_OCTETS, NULL, &vp->data) < 0) goto fail2;
-                               cast = &box;
-                       } else {
-                               cast = &vp->data;
+               if (in_vb->type != FR_TYPE_OCTETS) {
+                       if (fr_value_box_cast(ctx, &box, FR_TYPE_OCTETS, NULL, in_vb) < 0) {
+                       error:
+                               talloc_free(vb);
+                               RPEDEBUG("Failed packing value");
+                               return XLAT_ACTION_FAIL;
                        }
+                       cast = &box;
+               } else {
+                       cast = in_vb;
+               }
 
-                       if (vb->datum.length == 0) {
-                               (void) fr_value_box_memcpy(vb, vb, NULL, cast->vb_octets, cast->datum.length, cast->tainted);
+               if (vb->vb_length == 0) {
+                       (void) fr_value_box_memcpy(vb, vb, NULL, cast->vb_octets, cast->vb_length, cast->tainted);
 
-                       } else if (fr_value_box_append_mem(vb, cast->vb_octets, cast->datum.length, cast->tainted) < 0) {
-                       fail2:
-                               talloc_free(cursor);
-                               goto fail;
-                       }
-
-                       fr_assert(vb->vb_octets != NULL);
+               } else if (fr_value_box_append_mem(vb, cast->vb_octets, cast->vb_length, cast->tainted) < 0) {
+                       goto error;
                }
-               talloc_free(cursor);
+
+               fr_assert(vb->vb_octets != NULL);
        }
-       talloc_free(buffer);
 
        fr_cursor_append(out, vb);
 
        return XLAT_ACTION_DONE;
 }
 
-
 /** Encode attributes as a series of string attribute/value pairs
  *
  * This is intended to serialize one or more attributes as a comma