diff --git a/src/lib/util/dict_tokenize.c b/src/lib/util/dict_tokenize.c index 619692218088..f197f15d36dd 100644 --- a/src/lib/util/dict_tokenize.c +++ b/src/lib/util/dict_tokenize.c @@ -899,7 +899,7 @@ static int dict_process_ref(dict_tokenize_ctx_t *ctx, fr_dict_attr_t const *pare static int dict_read_process_attribute(dict_tokenize_ctx_t *ctx, char **argv, int argc, fr_dict_attr_flags_t const *base_flags) { - bool set_relative_attr = true; + bool set_relative_attr; ssize_t slen; unsigned int attr; @@ -931,11 +931,6 @@ static int dict_read_process_attribute(dict_tokenize_ctx_t *ctx, char **argv, in return -1; } - /* - * Relative OIDs apply ONLY to attributes of type 'tlv'. - */ - if (type != FR_TYPE_TLV) set_relative_attr = false; - /* * A non-relative ATTRIBUTE definition means that it is * in the context of the previous BEGIN-FOO. So we @@ -959,6 +954,11 @@ static int dict_read_process_attribute(dict_tokenize_ctx_t *ctx, char **argv, in if (slen <= 0) return -1; } + /* + * We allow relative attributes only for TLVs. + */ + set_relative_attr = (type == FR_TYPE_TLV); + } else { if (!ctx->relative_attr) { fr_strerror_const("Unknown parent for partial OID"); @@ -966,10 +966,11 @@ static int dict_read_process_attribute(dict_tokenize_ctx_t *ctx, char **argv, in } parent = ctx->relative_attr; - set_relative_attr = false; slen = fr_dict_attr_by_oid_legacy(ctx->dict, &parent, &attr, argv[1]); if (slen <= 0) return -1; + + set_relative_attr = false; } if (!fr_cond_assert(parent)) return -1; /* Should have provided us with a parent */ @@ -1029,18 +1030,9 @@ static int dict_read_process_attribute(dict_tokenize_ctx_t *ctx, char **argv, in */ da = dict_attr_child_by_num(parent, attr); if (!da) { - fr_strerror_printf("Failed to find attribute '%s' we just added.", argv[0]); - return -1; - } - -#ifndef NDEBUG - if (!dict_attr_by_name(NULL, parent, argv[0])) { - fr_strerror_printf("Failed to find attribute '%s' we just added.", argv[0]); + fr_strerror_printf("Failed to find attribute number %u we just added to parent %s.", attr, parent->name); return -1; } -#endif - - if (set_relative_attr) ctx->relative_attr = da; if (dict_process_ref(ctx, parent, da, ref) < 0) return -1; @@ -1055,6 +1047,8 @@ static int dict_read_process_attribute(dict_tokenize_ctx_t *ctx, char **argv, in memcpy(&ctx->value_attr, &da, sizeof(da)); } + if (set_relative_attr) ctx->relative_attr = da; + return 0; } @@ -1145,7 +1139,7 @@ static int dict_read_process_define(dict_tokenize_ctx_t *ctx, char **argv, int a da = dict_attr_by_name(NULL, parent, argv[0]); if (!da) { - fr_strerror_printf("Failed to find attribute '%s' we just added.", argv[0]); + fr_strerror_printf("Failed to find attribute '%s' we just added to parent %s", argv[0], parent->name); return -1; } @@ -1162,6 +1156,12 @@ static int dict_read_process_define(dict_tokenize_ctx_t *ctx, char **argv, int a memcpy(&ctx->value_attr, &da, sizeof(da)); } + if (type == FR_TYPE_TLV) { + ctx->relative_attr = da; + } else { + ctx->relative_attr = NULL; + } + return 0; } @@ -1248,16 +1248,9 @@ static int dict_read_process_enum(dict_tokenize_ctx_t *ctx, char **argv, int arg */ da = dict_attr_child_by_num(parent, attr); if (!da) { - fr_strerror_printf("Failed to find attribute '%s' we just added.", argv[0]); - return -1; - } - -#ifndef NDEBUG - if (!dict_attr_by_name(NULL, parent, argv[0])) { - fr_strerror_printf("Failed to find attribute '%s' we just added.", argv[0]); + fr_strerror_printf("Failed to find attribute number %u we just added to parent %s", attr, parent->name); return -1; } -#endif memcpy(&ctx->value_attr, &da, sizeof(da)); diff --git a/src/lib/util/dict_util.c b/src/lib/util/dict_util.c index c775a5bd45ad..e760f9a7af04 100644 --- a/src/lib/util/dict_util.c +++ b/src/lib/util/dict_util.c @@ -1080,7 +1080,10 @@ int dict_attr_child_add(fr_dict_attr_t *parent, fr_dict_attr_t *child) * The parent has children by name only, not by number. Don't even bother trying to track * numbers, except for VENDOR in root, and MEMBER of a struct. */ - if (!parent->flags.is_root && parent->flags.name_only && (parent->type != FR_TYPE_STRUCT)) return 0; + if (!parent->flags.is_root && parent->flags.name_only && + (parent->type != FR_TYPE_STRUCT) && (parent->type != FR_TYPE_TLV)) { + return 0; + } /* * We only allocate the pointer array *if* the parent has children. @@ -1269,6 +1272,9 @@ int fr_dict_attr_add(fr_dict_t *dict, fr_dict_attr_t const *parent, fr_dict_attr_t const *old; fr_dict_attr_flags_t our_flags = *flags; bool self_allocated = false; +#ifndef NDEBUG + fr_dict_attr_t const *da; +#endif if (unlikely(dict->read_only)) { fr_strerror_printf("%s dictionary has been marked as read only", fr_dict_root(dict)->name); @@ -1331,6 +1337,22 @@ int fr_dict_attr_add(fr_dict_t *dict, fr_dict_attr_t const *parent, */ if (dict_attr_child_add(UNCONST(fr_dict_attr_t *, parent), n) < 0) goto error; +#ifndef NDEBUG + /* + * Check if we added the attribute + */ + da = dict_attr_child_by_num(parent, n->attr); + if (!da) { + fr_strerror_printf("FATAL - Failed to find attribute number %u we just added to parent %s.", n->attr, parent->name); + return -1; + } + + if (!dict_attr_by_name(NULL, parent, n->name)) { + fr_strerror_printf("FATAL - Failed to find attribute '%s' we just added to parent %s.", n->name, parent->name); + return -1; + } +#endif + /* * If it's a group attribute, the default * reference goes to the root of the