From: Alan T. DeKok Date: Tue, 21 May 2019 14:58:05 +0000 (-0400) Subject: parse precision for attributes of type 'date' X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=777c40ff27babdc301a809446fcd720a4d3229df;p=thirdparty%2Ffreeradius-server.git parse precision for attributes of type 'date' --- diff --git a/src/lib/util/dict.c b/src/lib/util/dict.c index 37f1f4f273c..7a20d5bb9bd 100644 --- a/src/lib/util/dict.c +++ b/src/lib/util/dict.c @@ -177,6 +177,15 @@ bool const fr_dict_non_data_types[FR_TYPE_MAX + 1] = { [FR_TYPE_VENDOR] = true }; +static FR_NAME_NUMBER const date_precision_table[] = { + { "seconds", DATE_SECONDS }, + { "milliseconds", DATE_MILLISECONDS }, + { "microseconds", DATE_MICROSECONDS }, + { "nanoseconds", DATE_NANOSECONDS }, + + { NULL, 0 } +}; + /* * Create the hash of the name. * @@ -844,6 +853,15 @@ static bool dict_attr_fields_valid(fr_dict_t *dict, fr_dict_attr_t const *parent fr_int2str(fr_value_box_type_table, type, "?Unknown?")); return false; + case FR_TYPE_DATE: + if (flags->type_size > DATE_NANOSECONDS) { + fr_strerror_printf("Invalid precision '%d' for attribute of type 'date'", + flags->type_size); + return false; + } + break; + + default: break; } @@ -3908,7 +3926,7 @@ static int dict_process_type_field(char const *name, fr_type_t *type_p, fr_dict_ } -static int dict_process_flag_field(dict_from_file_ctx_t *ctx, char *name, fr_dict_attr_t const **ref_p, fr_dict_attr_flags_t *flags) +static int dict_process_flag_field(dict_from_file_ctx_t *ctx, char *name, fr_type_t type, fr_dict_attr_t const **ref_p, fr_dict_attr_flags_t *flags) { char *p, *q, *v; fr_dict_attr_t const *ref = NULL; @@ -3988,6 +4006,16 @@ static int dict_process_flag_field(dict_from_file_ctx_t *ctx, char *name, fr_dic *ref_p = ref; + } else if (type == FR_TYPE_DATE) { + int precision; + + precision = fr_str2int(date_precision_table, key, -1); + if (precision < 0) { + fr_strerror_printf("Unknown date precision '%s'", key); + return -1; + } + flags->type_size = precision; + } else { fr_strerror_printf("Unknown option '%s'", key); return -1; @@ -4083,7 +4111,7 @@ get_by_oid: /* * Parse options. */ - if ((argc >= 4) && (dict_process_flag_field(ctx, argv[3], &ref, &flags) < 0)) return -1; + if ((argc >= 4) && (dict_process_flag_field(ctx, argv[3], type, &ref, &flags) < 0)) return -1; #ifdef WITH_DICTIONARY_WARNINGS /* @@ -4164,7 +4192,7 @@ static int dict_read_process_member(dict_from_file_ctx_t *ctx, char **argv, int /* * Parse options. */ - if ((argc >= 3) && (dict_process_flag_field(ctx, argv[2], NULL, &flags) < 0)) return -1; + if ((argc >= 3) && (dict_process_flag_field(ctx, argv[2], type, NULL, &flags) < 0)) return -1; #ifdef __clang_analyzer__ if (!ctx->dict) return -1; diff --git a/src/lib/util/dict.h b/src/lib/util/dict.h index 78b70122943..ded81b694a9 100644 --- a/src/lib/util/dict.h +++ b/src/lib/util/dict.h @@ -85,6 +85,11 @@ typedef struct { extern const size_t dict_attr_sizes[FR_TYPE_MAX + 1][2]; extern fr_dict_t *fr_dict_internal; +#define DATE_SECONDS (0) +#define DATE_MILLISECONDS (1) +#define DATE_MICROSECONDS (2) +#define DATE_NANOSECONDS (3) + /** Dictionary attribute */ struct dict_attr {