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;
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;
}
if (!rules) rules = &default_rules;
+ fr_strerror_clear();
+
/*
* Set size for all fixed length attributes.
*/
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);
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;
# literals are parsed when the conditions are parsed
condition <integer>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,
match 00:11:22:33:44:55 == "%{md4:00:11:22:33:44:55}"
condition <ether> 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.
match true
condition <ipaddr>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 <ipaddr>127.0.0.1/32 == 127.0.0.1
match true