]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
no need to call dict_attr_acopy_enumv() for enum=...
authorAlan T. DeKok <aland@freeradius.org>
Tue, 25 Nov 2025 02:35:46 +0000 (21:35 -0500)
committerAlan T. DeKok <aland@freeradius.org>
Tue, 25 Nov 2025 03:02:37 +0000 (22:02 -0500)
now that the ext copy routine for enums does the casts

src/lib/util/dict_fixup.c
src/lib/util/dict_tokenize.c

index f3e7a40855b702f07acaf6b5ab37ff5c8d62c38a..29d88a8aeb09d572c575ad721c78ff7f6f3aae3b 100644 (file)
@@ -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);
index 52919e8d467463ee38961e43c0d134ea6c874d86..25c1038af295d2070f9fa851766096dbed5a08b3 100644 (file)
@@ -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;