From: Alan T. DeKok Date: Tue, 25 Nov 2025 02:35:46 +0000 (-0500) Subject: no need to call dict_attr_acopy_enumv() for enum=... X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=384bd46f1942f1bfec9cff628831aba1fc3a4e04;p=thirdparty%2Ffreeradius-server.git no need to call dict_attr_acopy_enumv() for enum=... now that the ext copy routine for enums does the casts --- diff --git a/src/lib/util/dict_fixup.c b/src/lib/util/dict_fixup.c index f3e7a40855b..29d88a8aeb0 100644 --- a/src/lib/util/dict_fixup.c +++ b/src/lib/util/dict_fixup.c @@ -702,7 +702,6 @@ int dict_fixup_clone_enum_enqueue(dict_fixup_ctx_t *fctx, fr_dict_attr_t *da, ch static inline CC_HINT(always_inline) int dict_fixup_clone_enum_apply(UNUSED dict_fixup_ctx_t *fctx, dict_fixup_clone_t *fixup) { fr_dict_attr_t const *src; - int copied; (void) fr_dict_protocol_reference(&src, fixup->da->parent, &FR_SBUFF_IN_STR(fixup->ref)); if (!src) { @@ -711,6 +710,20 @@ static inline CC_HINT(always_inline) int dict_fixup_clone_enum_apply(UNUSED dict return -1; } + if (!fr_dict_attr_ext(src, FR_DICT_ATTR_EXT_ENUMV)) { + fr_strerror_printf_push("Reference %s has no VALUEs defined at %s[%d]", + fixup->da->name, fr_cwd_strip(fixup->da->filename), fixup->da->line); + return -1; + } + + /* + * This must already exist. + */ + fr_assert(fr_dict_attr_ext(fixup->da, FR_DICT_ATTR_EXT_ENUMV)); + + /* + * @todo - allow this for leaf attributes. + */ if (src->dict->proto != fixup->da->dict->proto) { fr_strerror_printf("Incompatible protocols. Referenced '%s', referencing '%s'. Defined at %s[%d]", src->dict->proto->name, fixup->da->dict->proto->name, fixup->da->filename, fixup->da->line); @@ -728,25 +741,7 @@ static inline CC_HINT(always_inline) int dict_fixup_clone_enum_apply(UNUSED dict return -1; } - if (src->type != fixup->da->type) { - fr_strerror_printf("enum copy type mismatch. src '%s', dst '%s'", - fr_type_to_str(src->type), fr_type_to_str(fixup->da->type)); - return -1; - } - - /* - * We copy all of the VALUEs over from the source - * da by hand, by casting them. - * - * We have to do this work manually because we - * can't call dict_attr_acopy(), as that function - * copies the VALUE with the *source* data type, - * where we need the *destination* data type. - */ - copied = dict_attr_acopy_enumv(fixup->da, src); - if (copied < 0) return -1; - - if (!copied) { + if (!dict_attr_ext_copy(&fixup->da, src, FR_DICT_ATTR_EXT_ENUMV)) { fr_strerror_printf("Reference copied no VALUEs from type type '%s' at %s[%d]", fr_type_to_str(fixup->da->type), fr_cwd_strip(fixup->da->filename), fixup->da->line); diff --git a/src/lib/util/dict_tokenize.c b/src/lib/util/dict_tokenize.c index 52919e8d467..25c1038af29 100644 --- a/src/lib/util/dict_tokenize.c +++ b/src/lib/util/dict_tokenize.c @@ -525,18 +525,19 @@ FLAG_FUNC(counter) static int dict_flag_enum(fr_dict_attr_t **da_p, char const *value, UNUSED fr_dict_flag_parser_rule_t const *rule) { /* - * Allow enum=... as a synonym for - * "clone". We check the sources and not - * the targets, because that's easier. - * - * Plus, ENUMs are really just normal attributes - * in disguise. + * Allow enum=... as an almost synonym for "clone", where we copy only the VALUEs, and not any + * children. */ if (!fr_type_is_leaf((*da_p)->type)) { fr_strerror_const("'enum=...' references cannot be used for structural types"); return -1; } + /* + * Ensure that this attribute has room for enums. + */ + if (!dict_attr_ext_alloc(da_p, FR_DICT_ATTR_EXT_ENUMV)) return -1; + if (unlikely(dict_attr_ref_aunresolved(da_p, value, FR_DICT_ATTR_REF_ENUM) < 0)) return -1; return 0;