]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
respect casts
authorAlan T. DeKok <aland@freeradius.org>
Wed, 22 Jun 2022 18:25:10 +0000 (14:25 -0400)
committerAlan T. DeKok <aland@freeradius.org>
Thu, 23 Jun 2022 12:50:44 +0000 (08:50 -0400)
src/lib/unlang/xlat_eval.c

index 95dfe091f2bb296fa53232588673c62b52c2af53..26d87613cbd43b35464feac994153ea71e0dfb10 100644 (file)
@@ -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;