From: Alan T. DeKok Date: Sat, 23 Jul 2022 13:59:45 +0000 (-0400) Subject: add and use fr_pair_list_copy_to_box() X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2e3445557c5b4e7cc573f27f8b64660551ca31b5;p=thirdparty%2Ffreeradius-server.git add and use fr_pair_list_copy_to_box() as we can't call fr_value_box_copy() on vp->vp_group. --- diff --git a/src/lib/server/tmpl_eval.c b/src/lib/server/tmpl_eval.c index 69f2dafa6b1..528d683d61e 100644 --- a/src/lib/server/tmpl_eval.c +++ b/src/lib/server/tmpl_eval.c @@ -1338,8 +1338,21 @@ int tmpl_eval_pair(TALLOC_CTX *ctx, fr_value_box_list_t *out, request_t *request * shallow copying buffers. */ while (vp != NULL) { - value = fr_value_box_alloc(ctx, vp->data.type, vp->da, vp->data.tainted); - fr_value_box_copy(value, value, &vp->data); + if (fr_type_is_structural(vp->da->type)) { + value = fr_value_box_alloc(ctx, FR_TYPE_GROUP, NULL, false); + if (!value) goto oom; + + if (fr_pair_list_copy_to_box(value, &vp->vp_group) < 0) { + talloc_free(value); + goto oom; + } + + } else { + value = fr_value_box_alloc(ctx, vp->data.type, vp->da, vp->data.tainted); + if (!value) goto oom; + fr_value_box_copy(value, value, &vp->data); + } + fr_dlist_insert_tail(&list, value); vp = fr_dcursor_next(&cursor); } diff --git a/src/lib/util/pair.c b/src/lib/util/pair.c index 1635cbb70c4..95ddc85ec0d 100644 --- a/src/lib/util/pair.c +++ b/src/lib/util/pair.c @@ -1831,6 +1831,58 @@ int fr_pair_list_copy(TALLOC_CTX *ctx, fr_pair_list_t *to, fr_pair_list_t const return cnt; } + +/** Copy the contents of a pair list to a set of value-boxes + * + * This function should be removed when the xlats use dcursors + * of copying all of the boxes. + * + * @param[in] dst where boxes will be created + * @param[in] from whence to copy #fr_pair_t (s). + * @return + * - >0 the number of boxes copied. + * - 0 if no boxes copied. + * - -1 on error. + */ +int fr_pair_list_copy_to_box(fr_value_box_t *dst, fr_pair_list_t *from) +{ + int cnt = 0; + fr_value_box_t *value, *first_added = NULL; + fr_pair_t *vp; + + fr_assert(dst->type == FR_TYPE_GROUP); + + for (vp = fr_pair_list_head(from); + vp; + vp = fr_pair_list_next(from, vp), cnt++) { + PAIR_VERIFY_WITH_LIST(from, vp); + + if (fr_type_is_structural(vp->da->type)) { + value = fr_value_box_alloc(dst, FR_TYPE_GROUP, NULL, false); + if (!value) goto fail; + + if (fr_pair_list_copy_to_box(value, &vp->vp_group) < 0) { + talloc_free(value); + goto fail; + } + + } else { + value = fr_value_box_alloc(dst, vp->data.type, vp->da, vp->data.tainted); + if (!value) { + fail: + fr_dlist_talloc_free_to_tail(&dst->vb_group, first_added); + return -1; + } + fr_value_box_copy(value, value, &vp->data); + } + + if (!first_added) first_added = value; + fr_dlist_insert_tail(&dst->vb_group, value); + } + + return cnt; +} + /** Duplicate pairs in a list matching the specified da * * Copy all pairs from 'from' matching the specified da. diff --git a/src/lib/util/pair.h b/src/lib/util/pair.h index 7b6e90fc84d..99057f1dc6f 100644 --- a/src/lib/util/pair.h +++ b/src/lib/util/pair.h @@ -567,6 +567,8 @@ int fr_pair_list_copy(TALLOC_CTX *ctx, fr_pair_list_t *to, fr_pair_list_t const void fr_pair_list_steal(TALLOC_CTX *ctx, fr_pair_list_t *list); +int fr_pair_list_copy_to_box(fr_value_box_t *dst, fr_pair_list_t *from); + int fr_pair_list_copy_by_da(TALLOC_CTX *ctx, fr_pair_list_t *to, fr_pair_list_t const *from, fr_dict_attr_t const *da, unsigned int count);