]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
Better string parsing errors
authorArran Cudbard-Bell <a.cudbardb@freeradius.org>
Wed, 3 Nov 2021 03:25:22 +0000 (23:25 -0400)
committerArran Cudbard-Bell <a.cudbardb@freeradius.org>
Wed, 3 Nov 2021 03:25:22 +0000 (23:25 -0400)
src/lib/server/cond_tokenize.c
src/lib/util/value.c
src/tests/unit/condition/base.txt

index aab59b8db97efaebc0f9b57014075f553c321bd8..f6a1719c81d97d9b8a8fa45a6f2e5bbf19e64335 100644 (file)
@@ -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;
        }
 
index 79e036415d4f413dc5845cea1f1af343d111ca6c..2c3c7375da1bf4f87f64ecc12468b540437ce89d 100644 (file)
@@ -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;
index aeb5602ea0a2089075f52b61bf57bbe2cdfe5607..cbcc3aa39bb86508e0789a3fd76333ec818e736e 100644 (file)
@@ -219,10 +219,10 @@ condition &Event-Timestamp == 'January 1, 2012'
 
 # 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,
@@ -250,7 +250,7 @@ condition <ether> 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 <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.
@@ -331,7 +331,7 @@ condition <ipaddr>127.0.0.1/32 == 127.0.0.1
 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