#endif
/*
- * If our parent is a fixed-size struct, then we have to be fixed-size, too.
+ * If our parent is a known width struct, then we're
+ * allowed to be variable width. The parent might just
+ * have a "length=16" prefix, which lets its children be
+ * variable sized.
*/
- da->flags.is_known_width |= CURRENT_FRAME(dctx)->da->flags.is_known_width;
/*
* Double check any bit field magic
* to them.
*/
if (da->type == FR_TYPE_TLV) {
- dctx->relative_attr = dict_attr_child_by_num(CURRENT_FRAME(dctx)->da,
- CURRENT_FRAME(dctx)->member_num);
- if (dctx->relative_attr && (dict_dctx_push(dctx, dctx->relative_attr, NEST_NONE) < 0)) return -1;
+ dctx->relative_attr = da;
+ if (dict_dctx_push(dctx, dctx->relative_attr, NEST_NONE) < 0) return -1;
}
} else if (CURRENT_FRAME(dctx)->da->flags.length) {
ALLOW_FLAG(extra);
ALLOW_FLAG(subtype);
- if (parent->flags.is_known_width && !flags->is_known_width && !flags->length) {
+ /*
+ * If our parent is known width, then the children have to be known width, UNLESS
+ * either this child or its parent has a "length" prefix.
+ */
+ if (parent->flags.is_known_width && !flags->is_known_width && !flags->length &&
+ !da_is_length_field(da) && !da_is_length_field(parent)) {
fr_strerror_const("Variable-sized fields cannot be used within a 'struct' which is 'array'");
return false;
}