From: Alan T. DeKok Date: Sat, 23 Aug 2025 15:41:24 +0000 (-0400) Subject: better checks for parent / child lengths X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=d3a10001a02c94a6ad98ec78fe0d9573310b6c23;p=thirdparty%2Ffreeradius-server.git better checks for parent / child lengths --- diff --git a/src/lib/util/dict_tokenize.c b/src/lib/util/dict_tokenize.c index 16395e4315..d4674ebb98 100644 --- a/src/lib/util/dict_tokenize.c +++ b/src/lib/util/dict_tokenize.c @@ -2289,9 +2289,11 @@ static int dict_read_process_member(dict_tokenize_ctx_t *dctx, char **argv, int #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 @@ -2456,9 +2458,8 @@ static int dict_read_process_member(dict_tokenize_ctx_t *dctx, char **argv, int * 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) { diff --git a/src/lib/util/dict_validate.c b/src/lib/util/dict_validate.c index f2094195f6..6d12d1cec5 100644 --- a/src/lib/util/dict_validate.c +++ b/src/lib/util/dict_validate.c @@ -506,7 +506,12 @@ bool dict_attr_flags_valid(fr_dict_attr_t *da) 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; }