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;
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
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");
}
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 */
*/
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;
memcpy(&ctx->value_attr, &da, sizeof(da));
}
+ if (set_relative_attr) ctx->relative_attr = da;
+
return 0;
}
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;
}
memcpy(&ctx->value_attr, &da, sizeof(da));
}
+ if (type == FR_TYPE_TLV) {
+ ctx->relative_attr = da;
+ } else {
+ ctx->relative_attr = NULL;
+ }
+
return 0;
}
*/
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));
* 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.
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);
*/
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