Skip to content
Permalink
Browse files

add "key" flag for integer attributes

in preparation for allowing nested structs, decoded with a key
  • Loading branch information
alandekok committed Aug 7, 2019
1 parent 6b07de4 commit 6da1084f79b2cdc497dd32e44a27c2d50643a6ac
Showing with 70 additions and 3 deletions.
  1. +70 −3 src/lib/util/dict.c
@@ -928,7 +928,7 @@ static bool dict_attr_fields_valid(fr_dict_t *dict, fr_dict_attr_t const *parent
return false;
}

if (flags->internal || flags->has_tag || flags->array || flags->concat || flags->virtual) {
if (flags->internal || flags->has_tag || flags->array || flags->concat || flags->virtual || flags->extra) {
fr_strerror_printf("Invalid flag for attribute of type 'struct'");
return false;
}
@@ -958,6 +958,7 @@ static bool dict_attr_fields_valid(fr_dict_t *dict, fr_dict_attr_t const *parent
}

if (*attr > 1) {
int i;
fr_dict_attr_t const *sibling;

sibling = fr_dict_attr_child_by_num(parent, (*attr) - 1);
@@ -972,6 +973,44 @@ static bool dict_attr_fields_valid(fr_dict_t *dict, fr_dict_attr_t const *parent
return false;
}

/*
* Check for bad key fields, or multiple key fields.
*/
if (flags->extra) {
/*
* There should really be a
* separate "validation"
* function, which is used both
* here, and by the flag parser.
*/
switch (type) {
case FR_TYPE_UINT8:
case FR_TYPE_UINT16:
case FR_TYPE_UINT32:
case FR_TYPE_UINT64:
break;

default:
fr_strerror_printf("'key' can only be used with unsigned integer data types");
return -1;
}

for (i = 1; i < *attr; i++) {
sibling = fr_dict_attr_child_by_num(parent, i);
if (!sibling) {
fr_strerror_printf("Child %d of 'struct' type attribute %s does not exist.",
i, parent->name);
return false;
}

if (!sibling->flags.extra) continue;

fr_strerror_printf("Duplicate key attributes '%s' and '%s' in 'struct' type attribute %s are forbidden",
name, sibling->name, parent->name);
return false;
}
}

} else {
/*
* The first child can't be variable length, that's stupid.
@@ -2470,10 +2509,23 @@ do { \
}

if (flags->extra) {
if (type == FR_TYPE_EXTENDED) {
switch (type) {
case FR_TYPE_EXTENDED:
p += snprintf(p, end - p, "long,");
if (p >= end) return -1;
break;

case FR_TYPE_UINT8:
case FR_TYPE_UINT16:
case FR_TYPE_UINT32:
case FR_TYPE_UINT64:
p += snprintf(p, end - p, "key,");
break;

default:
break;
}

if (p >= end) return -1;
}

/*
@@ -4006,6 +4058,21 @@ static int dict_process_flag_field(dict_from_file_ctx_t *ctx, char *name, fr_typ

flags->extra = 1;

} else if (strcmp(key, "key") == 0) {
switch (type) {
case FR_TYPE_UINT8:
case FR_TYPE_UINT16:
case FR_TYPE_UINT32:
case FR_TYPE_UINT64:
break;

default:
fr_strerror_printf("'key' can only be used with unsigned integer data types");
return -1;
}

flags->extra = 1;

} else if (ref_p && (strcmp(key, "reference") == 0)) {
ref = dict_resolve_reference(ctx->dict, value);
if (!ref) return -1;

0 comments on commit 6da1084

Please sign in to comment.
You can’t perform that action at this time.