From: Alan T. DeKok Date: Wed, 22 Jun 2022 18:25:10 +0000 (-0400) Subject: respect casts X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=19d927cda24224d43700284f972c0b5237f517c8;p=thirdparty%2Ffreeradius-server.git respect casts --- diff --git a/src/lib/unlang/xlat_eval.c b/src/lib/unlang/xlat_eval.c index 95dfe091f2b..26d87613cbd 100644 --- a/src/lib/unlang/xlat_eval.c +++ b/src/lib/unlang/xlat_eval.c @@ -1378,6 +1378,61 @@ xlat_action_t xlat_frame_eval(TALLOC_CTX *ctx, fr_dcursor_t *out, xlat_exp_head_ fr_assert(0); } + /* + * Apply a cast to the results if required. + */ + if (tmpl_rules_cast(node->vpt) != FR_TYPE_NULL) { + fr_type_t cast = tmpl_rules_cast(node->vpt); + fr_value_box_t *vb; + bool tainted; + + vb = fr_dlist_head(&result); + + switch (cast) { + case FR_TYPE_STRING: + case FR_TYPE_OCTETS: + if (fr_value_box_list_concat_in_place(vb, vb, &result, cast, + FR_VALUE_BOX_LIST_FREE_BOX, true, SIZE_MAX) < 0) { + goto fail; + } + break; + + default: + /* + * One box, we cast it as the destination type. + * + * Many boxes, turn them into strings, and try to parse it as the + * output type. + */ + if (!fr_dlist_next(&result, vb)) { + if (fr_value_box_cast_in_place(vb, vb, cast, NULL) < 0) goto fail; + + } else { + ssize_t slen, vlen; + fr_sbuff_t *agg; + + FR_SBUFF_TALLOC_THREAD_LOCAL(&agg, 256, 256); + + slen = fr_value_box_list_concat_as_string(&tainted, agg, &result, NULL, 0, NULL, + FR_VALUE_BOX_LIST_FREE_BOX, true); + if (slen < 0) goto fail; + + MEM(vb = fr_value_box_alloc_null(ctx)); + vlen = fr_value_box_from_str(vb, vb, cast, NULL, + fr_sbuff_start(agg), fr_sbuff_used(agg), + NULL, tainted); + if ((vlen < 0) || (slen != vlen)) goto fail; + + fr_dlist_insert_tail(&result, vb); + } + break; + + case FR_TYPE_STRUCTURAL: + fr_assert(0); + goto fail; + } + } + xlat_debug_log_list_result(request, &result); fr_dlist_move(out->dlist, &result); continue;