From: Alan T. DeKok Date: Thu, 17 Mar 2022 22:53:18 +0000 (-0400) Subject: allow structs to be children of structs X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2b767cb034c8d56427be0777cdf4e5e0e1f8ea2b;p=thirdparty%2Ffreeradius-server.git allow structs to be children of structs ATTR foo struct member bar uint8 member baz struct member x # of 'baz' struct! member y It looks stupid, but it works. --- diff --git a/src/lib/util/dict_tokenize.c b/src/lib/util/dict_tokenize.c index e22df453b0d..27c1ddd525e 100644 --- a/src/lib/util/dict_tokenize.c +++ b/src/lib/util/dict_tokenize.c @@ -1084,6 +1084,7 @@ static int dict_read_process_member(dict_tokenize_ctx_t *ctx, char **argv, int a fr_type_t type; fr_dict_attr_flags_t flags; char *ref = NULL; + fr_dict_attr_t const *da; if ((argc < 2) || (argc > 3)) { fr_strerror_const("Invalid MEMBER syntax"); @@ -1182,8 +1183,6 @@ static int dict_read_process_member(dict_tokenize_ctx_t *ctx, char **argv, int a int i; for (i = 0; i <= ctx->stack[ctx->stack_depth].member_num; i++) { - fr_dict_attr_t const *da; - da = dict_attr_child_by_num(ctx->stack[ctx->stack_depth].da, i); if (!da) continue; /* really should be WTF? */ @@ -1210,6 +1209,15 @@ static int dict_read_process_member(dict_tokenize_ctx_t *ctx, char **argv, int a ++ctx->stack[ctx->stack_depth].member_num, type, &flags) < 0) return -1; + /* + * If we need to set the previous attribute, we have to + * look it up by number. This lets us set the + * *canonical* previous attribute, and not any potential + * duplicate which was just added. + */ + da = dict_attr_child_by_num(ctx->stack[ctx->stack_depth].da, ctx->stack[ctx->stack_depth].member_num); + fr_assert(da != NULL); + /* * A 'struct' can have a MEMBER of type 'tlv', but ONLY * as the last entry in the 'struct'. If we see that, @@ -1254,6 +1262,14 @@ static int dict_read_process_member(dict_tokenize_ctx_t *ctx, char **argv, int a if (ret < 0) return -1; } + /* + * Adding a member of type 'struct' is an implicit BEGIN-STRUCT. + */ + if (type == FR_TYPE_STRUCT) { + if (dict_gctx_push(ctx, da) < 0) return -1; + ctx->value_attr = NULL; + } + return 0; }