From: Alan T. DeKok Date: Sat, 1 Feb 2025 17:30:24 +0000 (-0500) Subject: do more compile-time checks of values. X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2b8351c622;p=thirdparty%2Ffreeradius-server.git do more compile-time checks of values. This is only for the modules "delay", "attr_filter", and "exec". Tho "exec" hasn't been updated yet, as it takes attributes. These modules should arguably be moved to the call_env framework. --- diff --git a/src/lib/server/cf_parse.c b/src/lib/server/cf_parse.c index f68a599bf66..643228fb762 100644 --- a/src/lib/server/cf_parse.c +++ b/src/lib/server/cf_parse.c @@ -262,6 +262,25 @@ int cf_pair_parse_value(TALLOC_CTX *ctx, void *out, UNUSED void *base, CONF_ITEM } fr_assert(vpt); + /* + * The caller told us what data type was expected. If we do have data, then try to cast + * it to the requested type. + */ + if ((rule->type != FR_TYPE_VOID) && tmpl_contains_data(vpt)) { + slen = 0; // for errors + + if (tmpl_is_data_unresolved(vpt)) { + tmpl_cast_set(vpt, rule->type); + + if (tmpl_resolve(vpt, NULL) < 0) goto tmpl_error; + + } else if (rule->type != tmpl_value_type(vpt)) { + fr_assert(tmpl_is_data(vpt)); + + if (tmpl_cast_in_place(vpt, rule->type, NULL) < 0) goto tmpl_error; + } + } + *(tmpl_t **)out = vpt; goto finish; } diff --git a/src/lib/server/cf_parse.h b/src/lib/server/cf_parse.h index 59e06a08354..aada8f866ed 100644 --- a/src/lib/server/cf_parse.h +++ b/src/lib/server/cf_parse.h @@ -244,6 +244,22 @@ _Generic(&(_ct), \ .flags = (_flags), \ .offset = FR_CONF_FLAG_CHECK((_type), (_flags), &(((_struct *)NULL)->_field), offsetof(_struct, _field)) +/** conf_parser_t which parses a single CONF_PAIR, writing the result to a field in a struct + * + * This variant takes output hint type. If the type is a bare word, it MUST be of the relevant data type. + * + * @param[in] _name of the CONF_PAIR to search for. + * @param[in] _type to parse the CONF_PAIR as. + * @param[in] _flags controlling parsing behaviour. + * @param[in] _struct containing the field to write the result to. + * @param[in] _field to write the result to. + */ +# define FR_CONF_OFFSET_HINT_TYPE(_name, _type, _struct, _field) \ + .name1 = _name, \ + .type = (_type), \ + .flags = CONF_FLAG_TMPL, \ + .offset = FR_CONF_FLAG_CHECK(FR_TYPE_VOID, CONF_FLAG_TMPL, &(((_struct *)NULL)->_field), offsetof(_struct, _field)) + /** conf_parser_t which parses a single CONF_PAIR, writing the result to a field in a struct * * This variant takes additional flags, and will add CONF_FLAG_MULTI automatically if the field is an array. diff --git a/src/lib/server/tmpl.h b/src/lib/server/tmpl.h index 91d10ca79bf..73804b593ea 100644 --- a/src/lib/server/tmpl.h +++ b/src/lib/server/tmpl.h @@ -226,10 +226,12 @@ typedef enum tmpl_type_e { #define tmpl_is_regex_xlat_unresolved(vpt) ((vpt)->type == TMPL_TYPE_REGEX_XLAT_UNRESOLVED) #define tmpl_needs_resolving(vpt) ((vpt)->type & TMPL_FLAG_UNRESOLVED) +#define tmpl_contains_data(vpt) ((vpt)->type & TMPL_TYPE_DATA) #define tmpl_contains_attr(vpt) ((vpt)->type & TMPL_FLAG_ATTR) #define tmpl_contains_regex(vpt) ((vpt)->type & TMPL_FLAG_REGEX) #define tmpl_contains_xlat(vpt) ((vpt)->type & TMPL_FLAG_XLAT) + extern fr_table_num_ordered_t const tmpl_type_table[]; extern size_t tmpl_type_table_len;