]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
do more compile-time checks of values.
authorAlan T. DeKok <aland@freeradius.org>
Sat, 1 Feb 2025 17:30:24 +0000 (12:30 -0500)
committerAlan T. DeKok <aland@freeradius.org>
Sat, 1 Feb 2025 17:30:24 +0000 (12:30 -0500)
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.

src/lib/server/cf_parse.c
src/lib/server/cf_parse.h
src/lib/server/tmpl.h

index f68a599bf66508570dd3bf995af7d4b17c538c8b..643228fb76297686d6d0fee7148e3dc8a45c1805 100644 (file)
@@ -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;
        }
index 59e06a083542918bf4396bfee4cfb5418350a7f9..aada8f866edabf5329af3a20783f7f5620805235 100644 (file)
@@ -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.
index 91d10ca79bfb14b9d39324d155e41e3094fac428..73804b593eaad5b598f5e39a56faf1e38eaffcd0 100644 (file)
@@ -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;