From 291496ddc6cc22d4f2679cd09d19c6d530d4843c Mon Sep 17 00:00:00 2001 From: "Alan T. DeKok" Date: Mon, 7 Mar 2022 09:15:26 -0500 Subject: [PATCH] add 'length=uint8' --- src/lib/util/dict.h | 3 ++- src/lib/util/dict_print.c | 8 ++++++-- src/lib/util/dict_tokenize.c | 23 +++++++++++++++++++---- src/lib/util/dict_validate.c | 8 ++++---- 4 files changed, 31 insertions(+), 11 deletions(-) diff --git a/src/lib/util/dict.h b/src/lib/util/dict.h index c130cea61e..1a0cdf4d23 100644 --- a/src/lib/util/dict.h +++ b/src/lib/util/dict.h @@ -134,12 +134,13 @@ enum { FLAG_EXTRA_NONE = 0, //!< no extra meaning, should be invalid FLAG_KEY_FIELD, //!< this is a key field for a subsequent struct FLAG_BIT_FIELD, //!< bit field inside of a struct + FLAG_LENGTH_UINT8, //!< string / octets type is prefixed by uint8 of length FLAG_LENGTH_UINT16, //!< string / octets type is prefixed by uint16 of length }; #define fr_dict_attr_is_key_field(_da) ((_da)->flags.extra && ((_da)->flags.subtype == FLAG_KEY_FIELD)) #define da_is_bit_field(_da) ((_da)->flags.extra && ((_da)->flags.subtype == FLAG_BIT_FIELD)) -#define da_is_length_field(_da) ((_da)->flags.extra && ((_da)->flags.subtype == FLAG_LENGTH_UINT16)) +#define da_is_length_field(_da) ((_da)->flags.extra && (((_da)->flags.subtype == FLAG_LENGTH_UINT16) || ((_da)->flags.subtype == FLAG_LENGTH_UINT16))) /** Extension identifier diff --git a/src/lib/util/dict_print.c b/src/lib/util/dict_print.c index 499bc4e2c6..23312e1882 100644 --- a/src/lib/util/dict_print.c +++ b/src/lib/util/dict_print.c @@ -70,11 +70,15 @@ ssize_t fr_dict_attr_flags_print(fr_sbuff_t *out, fr_dict_t const *dict, fr_type FR_SBUFF_IN_STRCPY_LITERAL_RETURN(&our_out, "key,"); break; - case FLAG_LENGTH_UINT16: + case FLAG_BIT_FIELD: FR_SBUFF_IN_STRCPY_LITERAL_RETURN(&our_out, "length=uint16,"); break; - case FLAG_BIT_FIELD: + case FLAG_LENGTH_UINT8: + FR_SBUFF_IN_STRCPY_LITERAL_RETURN(&our_out, "length=uint8,"); + break; + + case FLAG_LENGTH_UINT16: FR_SBUFF_IN_STRCPY_LITERAL_RETURN(&our_out, "length=uint16,"); break; diff --git a/src/lib/util/dict_tokenize.c b/src/lib/util/dict_tokenize.c index ac11db0f6f..e22df453b0 100644 --- a/src/lib/util/dict_tokenize.c +++ b/src/lib/util/dict_tokenize.c @@ -384,12 +384,23 @@ static int dict_process_flag_field(dict_tokenize_ctx_t *ctx, char *name, fr_type flags->subtype = FLAG_KEY_FIELD; } else if (strcmp(key, "length") == 0) { - if (!value || (strcmp(value, "uint16") != 0)) { - fr_strerror_const("The 'length' flag can only be used with value 'uint16'"); + if (!value) { + fr_strerror_const("The 'length' flag requires a value"); + return -1; } - flags->extra = 1; - flags->subtype = FLAG_LENGTH_UINT16; + if (strcmp(value, "uint8") == 0) { + flags->extra = 1; + flags->subtype = FLAG_LENGTH_UINT8; + + } else if (strcmp(value, "uint16") == 0) { + flags->extra = 1; + flags->subtype = FLAG_LENGTH_UINT16; + + } else { + fr_strerror_const("Invalid value given for the 'length' flag"); + return -1; + } } else if ((type == FR_TYPE_DATE) || (type == FR_TYPE_TIME_DELTA)) { /* @@ -1440,6 +1451,10 @@ static int dict_read_process_struct(dict_tokenize_ctx_t *ctx, char **argv, int a */ memset(&flags, 0, sizeof(flags)); + /* + * Structs can be prefixed with 16-bit lengths, but not + * with any other type of length. + */ if (argc == 4) { if (strcmp(argv[3], "length=uint16") != 0) { fr_strerror_printf("Unknown option '%s'", argv[3]); diff --git a/src/lib/util/dict_validate.c b/src/lib/util/dict_validate.c index 0c48e8e887..c860951220 100644 --- a/src/lib/util/dict_validate.c +++ b/src/lib/util/dict_validate.c @@ -165,8 +165,8 @@ bool dict_attr_flags_valid(fr_dict_t *dict, fr_dict_attr_t const *parent, * the data type. */ if (flags->extra) { - if ((flags->subtype != FLAG_KEY_FIELD) && (flags->subtype != FLAG_LENGTH_UINT16) && - (flags->subtype != FLAG_BIT_FIELD)) { + if ((flags->subtype != FLAG_KEY_FIELD) && (flags->subtype != FLAG_BIT_FIELD) && + (flags->subtype != FLAG_LENGTH_UINT8) && (flags->subtype != FLAG_LENGTH_UINT16)) { fr_strerror_const("The 'key' and 'length' flags cannot be used with any other flags."); return false; } @@ -209,7 +209,7 @@ bool dict_attr_flags_valid(fr_dict_t *dict, fr_dict_attr_t const *parent, if (flags->array) { ALLOW_FLAG(array); - if (flags->subtype != FLAG_LENGTH_UINT16) goto invalid_extra; + if ((flags->subtype != FLAG_LENGTH_UINT8) && (flags->subtype != FLAG_LENGTH_UINT16)) goto invalid_extra; } else if (flags->subtype) { invalid_extra: fr_strerror_const("Invalid type for extra flag."); @@ -243,7 +243,7 @@ bool dict_attr_flags_valid(fr_dict_t *dict, fr_dict_attr_t const *parent, return false; } - if ((flags->subtype == FLAG_LENGTH_UINT16) && + if (((flags->subtype == FLAG_LENGTH_UINT8) || (flags->subtype == FLAG_LENGTH_UINT16)) && ((type != FR_TYPE_STRING) && (type != FR_TYPE_OCTETS) && (type != FR_TYPE_STRUCT))) { fr_strerror_printf("The 'length' flag cannot be used used with type %s", fr_type_to_str(type)); -- 2.47.3