From: Arran Cudbard-Bell Date: Wed, 3 Nov 2021 03:25:22 +0000 (-0400) Subject: Better string parsing errors X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=da4494c66991435da3b63e54d24fe191a61d3268;p=thirdparty%2Ffreeradius-server.git Better string parsing errors --- diff --git a/src/lib/server/cond_tokenize.c b/src/lib/server/cond_tokenize.c index aab59b8db97..f6a1719c81d 100644 --- a/src/lib/server/cond_tokenize.c +++ b/src/lib/server/cond_tokenize.c @@ -193,9 +193,11 @@ static int cond_cast_tmpl(tmpl_t *vpt, fr_type_t type, tmpl_t *other) da = NULL; } + fr_strerror_clear(); + if (tmpl_cast_in_place(vpt, type, da) < 0) { - fr_strerror_printf("Failed parsing value as type '%s'", - fr_table_str_by_value(fr_value_box_type_table, type, "??")); + fr_strerror_printf_push("Failed parsing value as type '%s'", + fr_table_str_by_value(fr_value_box_type_table, type, "??")); return -1; } diff --git a/src/lib/util/value.c b/src/lib/util/value.c index 79e036415d4..2c3c7375da1 100644 --- a/src/lib/util/value.c +++ b/src/lib/util/value.c @@ -4258,7 +4258,7 @@ void fr_value_box_increment(fr_value_box_t *vb) static inline CC_HINT(always_inline) fr_slen_t fr_value_box_from_numeric_substr(fr_value_box_t *dst, fr_type_t dst_type, fr_dict_attr_t const *dst_enumv, - fr_sbuff_t *in, bool tainted) + fr_sbuff_t *in, fr_sbuff_parse_rules_t const *rules, bool tainted) { fr_slen_t slen; fr_sbuff_parse_error_t err; @@ -4315,7 +4315,26 @@ fr_slen_t fr_value_box_from_numeric_substr(fr_value_box_t *dst, fr_type_t dst_ty return -1; } - if (slen < 0) fr_sbuff_parse_error_to_strerror(err); + if (slen < 0) { + /* + * If an enumeration attribute is provided and we + * don't find an integer, assume this is an enumv + * lookup fail, and produce a better error. + */ + if (dst_enumv && dst_enumv->flags.has_value && (err == FR_SBUFF_PARSE_ERROR_NOT_FOUND)) { + fr_sbuff_t our_in = FR_SBUFF(in); + fr_sbuff_adv_until(&our_in, SIZE_MAX, rules->terminals, + rules->escapes ? rules->escapes->chr : '\0'); + + fr_strerror_printf("Invalid enumeration value \"%pV\" for %s", + fr_box_strvalue_len(fr_sbuff_start(&our_in), fr_sbuff_used(&our_in)), + dst_enumv->name); + return -1; + } + + fr_sbuff_parse_error_to_strerror(err); + } + return slen; } @@ -4348,6 +4367,8 @@ ssize_t fr_value_box_from_substr(TALLOC_CTX *ctx, fr_value_box_t *dst, if (!rules) rules = &default_rules; + fr_strerror_clear(); + /* * Set size for all fixed length attributes. */ @@ -4571,7 +4592,7 @@ parse: case FR_TYPE_INT64: case FR_TYPE_FLOAT32: case FR_TYPE_FLOAT64: - return fr_value_box_from_numeric_substr(dst, dst_type, dst_enumv, in, tainted); + return fr_value_box_from_numeric_substr(dst, dst_type, dst_enumv, in, rules, tainted); case FR_TYPE_BOOL: fr_value_box_init(dst, dst_type, dst_enumv, tainted); @@ -4647,27 +4668,31 @@ parse: return fr_sbuff_error(&our_in); } - if (!fr_sbuff_next_if_char(&our_in, ':')) goto ether_error; + if (!fr_sbuff_next_if_char(&our_in, ':')) { + ether_sep_error: + fr_strerror_const("Missing separator, expected ':'"); + return fr_sbuff_error(&our_in); + } fr_base16_decode(&err, &dbuff, &our_in, true); if (err != FR_SBUFF_PARSE_OK) goto ether_error; - if (!fr_sbuff_next_if_char(&our_in, ':')) goto ether_error; + if (!fr_sbuff_next_if_char(&our_in, ':')) goto ether_sep_error; fr_base16_decode(&err, &dbuff, &our_in, true); if (err != FR_SBUFF_PARSE_OK) goto ether_error; - if (!fr_sbuff_next_if_char(&our_in, ':')) goto ether_error; + if (!fr_sbuff_next_if_char(&our_in, ':')) goto ether_sep_error; fr_base16_decode(&err, &dbuff, &our_in, true); if (err != FR_SBUFF_PARSE_OK) goto ether_error; - if (!fr_sbuff_next_if_char(&our_in, ':')) goto ether_error; + if (!fr_sbuff_next_if_char(&our_in, ':')) goto ether_sep_error; fr_base16_decode(&err, &dbuff, &our_in, true); if (err != FR_SBUFF_PARSE_OK) goto ether_error; - if (!fr_sbuff_next_if_char(&our_in, ':')) goto ether_error; + if (!fr_sbuff_next_if_char(&our_in, ':')) goto ether_sep_error; fr_base16_decode(&err, &dbuff, &our_in, true); if (err != FR_SBUFF_PARSE_OK) goto ether_error; diff --git a/src/tests/unit/condition/base.txt b/src/tests/unit/condition/base.txt index aeb5602ea0a..cbcc3aa39bb 100644 --- a/src/tests/unit/condition/base.txt +++ b/src/tests/unit/condition/base.txt @@ -219,10 +219,10 @@ condition &Event-Timestamp == 'January 1, 2012' # literals are parsed when the conditions are parsed condition X == 1 -match ERROR offset 9: Failed parsing value as type 'uint32' +match ERROR offset 9: token not found: Failed parsing value as type 'uint32' condition &NAS-Port == X -match ERROR offset 13: Failed parsing value as type 'uint32' +match ERROR offset 13: token not found: Failed parsing value as type 'uint32' # # The RHS is a static string, so this gets mashed to a literal, @@ -250,7 +250,7 @@ condition 00:11:22:33:44:55 == "%{md4:00:11:22:33:44:55}" match 00:11:22:33:44:55 == "%{md4:00:11:22:33:44:55}" condition 00:XX:22:33:44:55 == 00:11:22:33:44:55 -match ERROR offset 8: Failed parsing value as type 'ether' +match ERROR offset 8: Missing separator, expected ':': Failed parsing value as type 'ether' # # Tests for boolean data types. @@ -331,7 +331,7 @@ condition 127.0.0.1/32 == 127.0.0.1 match true condition 127.0.0.1/327 == 127.0.0.1 -match ERROR offset 8: Failed parsing value as type 'ipaddr' +match ERROR offset 8: Invalid IPv4 mask length "/327". Should be between 0-32: Failed parsing value as type 'ipaddr' condition 127.0.0.1/32 == 127.0.0.1 match true