]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
Various fixes
authorArran Cudbard-Bell <a.cudbardb@freeradius.org>
Wed, 17 Mar 2021 16:04:51 +0000 (16:04 +0000)
committerArran Cudbard-Bell <a.cudbardb@freeradius.org>
Wed, 17 Mar 2021 16:04:57 +0000 (16:04 +0000)
src/lib/server/tmpl_eval.c
src/lib/unlang/xlat_builtin.c
src/lib/unlang/xlat_eval.c
src/lib/util/dlist.h
src/lib/util/value.c
src/lib/util/value.h

index 74e5b4c43ddb00dc8a76a0d1d4228c08a3066331..3de06213cf2577d9b934339c10667b258c5d2478 100644 (file)
@@ -557,7 +557,7 @@ ssize_t _tmpl_to_atype(TALLOC_CTX *ctx, void *out,
                       xlat_escape_legacy_t escape, void const *escape_ctx,
                       fr_type_t dst_type)
 {
-       fr_value_box_t const    *to_cast = NULL;
+       fr_value_box_t          *to_cast = NULL;
        fr_value_box_t          from_cast;
 
        fr_pair_t               *vp = NULL;
@@ -687,7 +687,7 @@ ssize_t _tmpl_to_atype(TALLOC_CTX *ctx, void *out,
        {
                RDEBUG4("EXPAND TMPL DATA");
 
-               to_cast = tmpl_value(vpt);
+               to_cast = UNCONST(fr_value_box_t *, tmpl_value(vpt));
                switch (to_cast->type) {
                case FR_TYPE_STRING:
                case FR_TYPE_OCTETS:
index 4738e1688d73bdac57d7c8b4ae53907c052766f9..de97d672aeed4bdd2b0f41d492528e86e74a9c98 100644 (file)
@@ -1827,16 +1827,16 @@ static xlat_action_t xlat_func_bin(TALLOC_CTX *ctx, fr_dcursor_t *out,
        uint8_t                 *bin;
        size_t                  len, outlen;
        fr_sbuff_parse_error_t  err;
-       fr_value_box_t          *in_head;
+       fr_value_box_t          *hex;
 
-       in_head = fr_dlist_head(in);
-       len = in_head->vb_length;
+       hex = fr_dlist_head(in);
+       len = hex->vb_length;
        if ((len > 1) && (len & 0x01)) {
                REDEBUG("Input data length must be >1 and even, got %zu", len);
                return XLAT_ACTION_FAIL;
        }
 
-       p = in_head->vb_strvalue;
+       p = hex->vb_strvalue;
        end = p + len;
 
        /*
@@ -1940,24 +1940,30 @@ static xlat_arg_parser_t const xlat_func_hex_arg = {
  *
  * @ingroup xlat_functions
  */
-static xlat_action_t xlat_func_hex(TALLOC_CTX *ctx, fr_dcursor_t *out, UNUSED request_t *request,
+static xlat_action_t xlat_func_hex(UNUSED TALLOC_CTX *ctx, fr_dcursor_t *out, UNUSED request_t *request,
                                   UNUSED void const *xlat_inst, UNUSED void *xlat_thread_inst,
                                   fr_value_box_list_t *in)
 {
-       char *p;
-       fr_value_box_t* vb;
-       fr_value_box_t* in_head;
-
-       in_head = fr_dlist_head(in);
+       char            *new_buff;
+       fr_value_box_t  *bin = fr_dlist_pop_head(in);   /* First argument */
 
-       MEM(vb = fr_value_box_alloc(ctx, FR_TYPE_STRING, NULL, false));
-       vb->vb_length = (in_head->vb_length * 2);
-       vb->vb_strvalue = p = talloc_zero_array(vb, char, vb->vb_length + 1);
-       if (in_head->vb_length) {
-               fr_bin2hex(&FR_SBUFF_OUT(p, talloc_array_length(p)), &FR_DBUFF_TMP(in_head->vb_octets, in_head->vb_length), SIZE_MAX);
+       /*
+        *      Use existing box, but with new buffer
+        */
+       MEM(new_buff = talloc_zero_array(bin, char, (bin->vb_length * 2) + 1));
+       if (bin->vb_length) {
+               fr_bin2hex(&FR_SBUFF_OUT(new_buff, (bin->vb_length * 2) + 1),
+                                        &FR_DBUFF_TMP(bin->vb_octets, bin->vb_length), SIZE_MAX);
+               fr_value_box_clear_value(bin);
+               fr_value_box_strdup_shallow(bin, NULL, new_buff, bin->tainted);
+       /*
+        *      Zero length binary > zero length hex string
+        */
+       } else {
+               fr_value_box_clear_value(bin);
+               fr_value_box_strdup(bin, bin, NULL, "", bin->tainted);
        }
-
-       fr_dcursor_append(out, vb);
+       fr_dcursor_append(out, bin);
 
        return XLAT_ACTION_DONE;
 }
index 41f569ca6cf2a3be655614ff1d2fe4d6ea10110c..6c0eb55d89e67f26206e061c4a1c76eeb02f704b 100644 (file)
@@ -1037,25 +1037,27 @@ xlat_action_t xlat_frame_eval_repeat(TALLOC_CTX *ctx, fr_dcursor_t *out,
                        xlat_thread_inst_t      *thread_inst;
                        fr_value_box_list_t     result_copy;
 
-                       fr_value_box_list_init(&result_copy);
                        thread_inst = xlat_thread_instance_find(node);
 
                        XLAT_DEBUG("** [%i] %s(func-async) - %%{%s:%pM}",
                                   unlang_interpret_stack_depth(request), __FUNCTION__,
                                   node->fmt, result);
 
+                       VALUE_BOX_LIST_VERIFY(result);
                        /*
                         *      Need to copy the input list in case
                         *      the async function mucks with it.
                         */
-                       if (RDEBUG_ENABLED2) fr_value_box_list_acopy(NULL, &result_copy, result);
-
-                       VALUE_BOX_LIST_VERIFY(result);
+                       if (RDEBUG_ENABLED2) {
+                               fr_value_box_list_init(&result_copy);
+                               fr_value_box_list_acopy(NULL, &result_copy, result);
+                       }
                        xa = xlat_process_args(ctx, result, request, node->call.func->input_type, node->call.func->args);
                        if (xa == XLAT_ACTION_FAIL) {
                                if (RDEBUG_ENABLED2) fr_dlist_talloc_free(&result_copy);
                                return xa;
                        }
+                       VALUE_BOX_LIST_VERIFY(result);
 
                        xa = node->call.func->func.async(ctx, out, request,
                                                         node->call.inst->data, thread_inst->data, result);
@@ -1170,6 +1172,8 @@ xlat_action_t xlat_frame_eval_repeat(TALLOC_CTX *ctx, fr_dcursor_t *out,
                xlat_debug_log_expansion(request, *in, NULL);
                xlat_debug_log_result(request, value);
 
+               VALUE_BOX_VERIFY(value);
+
                fr_dcursor_insert(out, value);
        }
                break;
@@ -1228,6 +1232,7 @@ xlat_action_t xlat_frame_eval(TALLOC_CTX *ctx, fr_dcursor_t *out, xlat_exp_t con
        for (node = *in; node; node = (*in)->next) {
                *in = node;             /* Update node in our caller */
                fr_dcursor_tail(out);   /* Needed for debugging */
+               VALUE_BOX_LIST_VERIFY(out->dlist);
 
                switch (node->type) {
                case XLAT_LITERAL:
@@ -1380,6 +1385,7 @@ xlat_action_t xlat_frame_eval(TALLOC_CTX *ctx, fr_dcursor_t *out, xlat_exp_t con
        }
 
 finish:
+       VALUE_BOX_LIST_VERIFY(out->dlist);
        XLAT_DEBUG("** [%i] %s << %s", unlang_interpret_stack_depth(request),
                   __FUNCTION__, fr_table_str_by_value(xlat_action_table, xa, "<INVALID>"));
 
index bb1889e4e7137405f4db6b0cce28db0bbb813060..d0de511a2ed0b36dd18860700d7f6e290a02e13b 100644 (file)
@@ -565,7 +565,7 @@ static inline void *fr_dlist_replace(fr_dlist_head_t *list_head, void *item, voi
  * Does nothing if the list was not initialised with #fr_dlist_talloc_init.
  */
 #ifndef TALLOC_GET_TYPE_ABORT_NOOP
-static inline CC_HINT(nonnull) void fr_dlist_verify(char const *file, int line, fr_dlist_head_t *list_head)
+static inline CC_HINT(nonnull) void fr_dlist_verify(char const *file, int line, fr_dlist_head_t const *list_head)
 {
        void *item;
 
index 6a0a325ac60044ec1bd677be23867152638ec8c3..073fc858e8a7ad5f9492bf0966c41fa36e8c2647 100644 (file)
@@ -492,6 +492,15 @@ static inline void fr_value_box_copy_meta(fr_value_box_t *dst, fr_value_box_t co
        case FR_TYPE_VARIABLE_SIZE:
                dst->vb_length = src->vb_length;
                break;
+       /*
+        *      Not 100% sure this should be done here
+        *      but if the intent is to make a null
+        *      box usable, then we need to do this
+        *      somewhere.
+        */
+       case FR_TYPE_GROUP:
+               fr_value_box_list_init(&dst->vb_group);
+               break;
 
        default:
                break;
@@ -3148,7 +3157,7 @@ void fr_value_box_clear_value(fr_value_box_t *data)
                talloc_free(data->datum.ptr);
                break;
 
-       case FR_TYPE_STRUCTURAL:
+       case FR_TYPE_GROUP:
                /*
                 *      Depth first freeing of children
                 *
@@ -3158,7 +3167,7 @@ void fr_value_box_clear_value(fr_value_box_t *data)
                {
                        fr_value_box_t  *vb = NULL;
 
-                       while ((vb = fr_dlist_next(&data->datum.children, vb))) {
+                       while ((vb = fr_dlist_next(&data->vb_group, vb))) {
                                fr_value_box_clear_value(vb);
                                talloc_free(vb);
                        }
@@ -3207,6 +3216,7 @@ int fr_value_box_copy(TALLOC_CTX *ctx, fr_value_box_t *dst, const fr_value_box_t
                memcpy(((uint8_t *)dst) + fr_value_box_offsets[src->type],
                       ((uint8_t const *)src) + fr_value_box_offsets[src->type],
                       fr_value_box_field_sizes[src->type]);
+               fr_value_box_copy_meta(dst, src);
                break;
 
        case FR_TYPE_STRING:
@@ -3222,6 +3232,7 @@ int fr_value_box_copy(TALLOC_CTX *ctx, fr_value_box_t *dst, const fr_value_box_t
                        return -1;
                }
                dst->vb_strvalue = str;
+               fr_value_box_copy_meta(dst, src);
        }
                break;
 
@@ -3238,11 +3249,41 @@ int fr_value_box_copy(TALLOC_CTX *ctx, fr_value_box_t *dst, const fr_value_box_t
                        talloc_set_type(bin, uint8_t);
                }
                dst->vb_octets = bin;
+               fr_value_box_copy_meta(dst, src);
        }
                break;
-       }
 
-       fr_value_box_copy_meta(dst, src);
+       case FR_TYPE_GROUP:
+       {
+               fr_value_box_t *child;
+
+               fr_value_box_copy_meta(dst, src);       /* Initialises group child dlist */
+
+               while ((child = fr_dlist_next(&src->vb_group, child))) {
+                       fr_value_box_t *new;
+
+                       /*
+                        *      Build out the child
+                        */
+                       new = fr_value_box_alloc_null(ctx);
+                       if (unlikely(!new)) {
+                       group_error:
+                               fr_strerror_const("Failed duplicating group child");
+                               fr_dlist_talloc_free(&dst->vb_group);
+                               return -1;
+                       }
+
+                       /*
+                        *      Populate it with the
+                        *      data from the original
+                        *      child.
+                        */
+                       if (unlikely(fr_value_box_copy(new, new, child) < 0)) goto group_error;
+                       fr_dlist_insert_tail(&dst->vb_group, new);
+               }
+       }
+               break;
+       }
 
        return 0;
 }
@@ -3282,7 +3323,7 @@ void fr_value_box_copy_shallow(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_value_bo
  *     - 0 on success.
  *     - -1 on failure.
  */
-int fr_value_box_steal(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_value_box_t const *src)
+int fr_value_box_steal(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_value_box_t *src)
 {
        if (!fr_cond_assert(src->type != FR_TYPE_NULL)) return -1;
 
@@ -3302,6 +3343,7 @@ int fr_value_box_steal(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_value_box_t cons
                talloc_set_type(str, char);
                dst->vb_strvalue = str;
                fr_value_box_copy_meta(dst, src);
+               memset(&src->datum, 0, sizeof(src->datum));
        }
                return 0;
 
@@ -3318,6 +3360,22 @@ int fr_value_box_steal(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_value_box_t cons
 
                dst->vb_octets = bin;
                fr_value_box_copy_meta(dst, src);
+               memset(&src->datum, 0, sizeof(src->datum));
+       }
+               return 0;
+
+       case FR_TYPE_GROUP:
+       {
+               fr_value_box_t *child;
+
+               while ((child = fr_dlist_pop_head(&src->vb_group))) {
+                       child = talloc_steal(ctx, child);
+                       if (unlikely(!child)) {
+                               fr_strerror_const("Failed stealing child");
+                               return -1;
+                       }
+                       fr_dlist_insert_tail(&dst->vb_group, child);
+               }
        }
                return 0;
        }
@@ -5213,9 +5271,9 @@ void value_box_verify(char const *file, int line, fr_value_box_t const *vb)
 
 void value_box_list_verify(char const *file, int line, fr_value_box_list_t const *list)
 {
-       fr_value_box_t const *vb;
+       fr_value_box_t const *vb = NULL;
 
        FR_DLIST_VERIFY(list);
 
-       while ((vb = fr_dlist_next(list, vb))) value_box_verify(file, line, list);
+       while ((vb = fr_dlist_next(list, vb))) value_box_verify(file, line, vb);
 }
index 466fce1d4b86717636a30f9e418f1ac12edfa6d8..feb84d336dd3e22bc7d37ec62ca06d8b66b0cf6c 100644 (file)
@@ -314,7 +314,7 @@ static inline bool fr_value_box_list_len_min(fr_value_box_list_t const *list, si
  */
 static inline void fr_value_box_list_init(fr_value_box_list_t *list)
 {
-       fr_dlist_talloc_init(list, fr_value_box_t, entry);
+       fr_dlist_init(list, fr_value_box_t, entry);     /* Not always talloced */
 }
 /** @} */
 
@@ -623,7 +623,7 @@ int         fr_value_box_copy(TALLOC_CTX *ctx, fr_value_box_t *dst, const fr_value_box_
 void           fr_value_box_copy_shallow(TALLOC_CTX *ctx, fr_value_box_t *dst,
                                          const fr_value_box_t *src);
 
-int            fr_value_box_steal(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_value_box_t const *src);
+int            fr_value_box_steal(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_value_box_t *src);
 /** @} */
 
 /** @name Assign and manipulate binary-unsafe C strings