From: Alan T. DeKok Date: Thu, 19 Mar 2026 20:23:50 +0000 (-0400) Subject: in some cases, "no data" is a parse error X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=eaae3be9d60184b1df4db7bc26d32171bc9cef20;p=thirdparty%2Ffreeradius-server.git in some cases, "no data" is a parse error and add tests to match --- diff --git a/src/lib/util/time.c b/src/lib/util/time.c index b3028743713..6b431e9b9b2 100644 --- a/src/lib/util/time.c +++ b/src/lib/util/time.c @@ -413,6 +413,11 @@ fr_slen_t fr_time_delta_from_str(fr_time_delta_t *out, char const *in, size_t in { fr_slen_t slen; + if (!*in) { + fr_strerror_const("Empty input is invalid"); + return -1; + } + slen = fr_time_delta_from_substr(out, &FR_SBUFF_IN(in, inlen), hint, true, NULL); if (slen < 0) return slen; if (slen != (fr_slen_t)inlen) { @@ -803,6 +808,11 @@ int fr_unix_time_from_str(fr_unix_time_t *date, char const *date_str, fr_time_re unsigned long l; fr_time_delta_t gmt_delta = fr_time_delta_wrap(0); + if (!*date_str) { + fr_strerror_const("Empty input is invalid"); + return -1; + } + /* * Test for unix timestamp, which is just a number and * nothing else. diff --git a/src/lib/util/value.c b/src/lib/util/value.c index 940826b57f0..2d503144f20 100644 --- a/src/lib/util/value.c +++ b/src/lib/util/value.c @@ -5375,7 +5375,6 @@ fr_slen_t fr_value_box_from_numeric_substr(fr_value_box_t *dst, fr_type_t dst_ty } } - return slen; } @@ -5623,7 +5622,7 @@ parse: case FR_TYPE_IPV4_ADDR: { size_t name_len = fr_sbuff_adv_past_allowed(&our_in, fr_sbuff_remaining(&our_in), sbuff_char_class_hostname, rules->terminals); - if (!name_len) return 0; + if (!name_len) goto empty_is_invalid; if (fr_inet_pton4(&addr, fr_sbuff_current(in), name_len, fr_hostname_lookups, false, true) < 0) return -1; @@ -5646,7 +5645,7 @@ parse: case FR_TYPE_IPV4_PREFIX: { size_t name_len = fr_sbuff_adv_past_allowed(&our_in, fr_sbuff_remaining(&our_in), sbuff_char_class_hostname, rules->terminals); - if (!name_len) return 0; + if (!name_len) goto empty_is_invalid; if (fr_inet_pton4(&dst->vb_ip, fr_sbuff_current(in), name_len, fr_hostname_lookups, false, true) < 0) return -1; @@ -5656,7 +5655,7 @@ parse: case FR_TYPE_IPV6_ADDR: { size_t name_len = fr_sbuff_adv_past_allowed(&our_in, fr_sbuff_remaining(&our_in), sbuff_char_class_hostname, rules->terminals); - if (!name_len) return 0; + if (!name_len) goto empty_is_invalid; /* * Parse scope, too. @@ -5686,7 +5685,7 @@ parse: case FR_TYPE_IPV6_PREFIX: { size_t name_len = fr_sbuff_adv_past_allowed(&our_in, fr_sbuff_remaining(&our_in), sbuff_char_class_hostname, rules->terminals); - if (!name_len) return 0; + if (!name_len) goto empty_is_invalid; if (fr_inet_pton6(&dst->vb_ip, fr_sbuff_current(in), name_len, fr_hostname_lookups, false, true) < 0) return -1; @@ -5696,7 +5695,7 @@ parse: case FR_TYPE_COMBO_IP_ADDR: { size_t name_len = fr_sbuff_adv_past_allowed(&our_in, fr_sbuff_remaining(&our_in), sbuff_char_class_hostname, rules->terminals); - if (!name_len) return 0; + if (!name_len) goto empty_is_invalid; /* * Parse scope, too. @@ -5723,7 +5722,7 @@ parse: case FR_TYPE_COMBO_IP_PREFIX: { size_t name_len = fr_sbuff_adv_past_allowed(&our_in, fr_sbuff_remaining(&our_in), sbuff_char_class_hostname, rules->terminals); - if (!name_len) return 0; + if (!name_len) goto empty_is_invalid; if (fr_inet_pton(&dst->vb_ip, fr_sbuff_current(in), name_len, AF_UNSPEC, fr_hostname_lookups, true) < 0) return -1; @@ -5753,7 +5752,7 @@ parse: * Quoted boolean values are "yes", "no", "true", "false" */ slen = fr_sbuff_out(NULL, &dst->vb_bool, in); - if (slen >= 0) return slen; + if (slen > 0) return slen; /* * For barewords we also allow 0 for false and any other @@ -5867,6 +5866,11 @@ parse: dst_enumv ? dst_enumv->flags.flag_time_res : FR_TIME_RES_SEC, false, rules->terminals); if (slen < 0) return slen; + if (!slen) { + empty_is_invalid: + fr_strerror_const("Empty input is invalid"); + return -1; + } FR_SBUFF_SET_RETURN(in, &our_in); case FR_TYPE_NULL: diff --git a/src/tests/unit/data_types.txt b/src/tests/unit/data_types.txt index 98e185b53eb..d9483db360c 100644 --- a/src/tests/unit/data_types.txt +++ b/src/tests/unit/data_types.txt @@ -1,5 +1,4 @@ fuzzer-out util - # # Parse / print data types # @@ -124,6 +123,77 @@ match -128 value int8 -130 match integer underflow +# +# Empty input is invalid for IP address types. +# +# The "!" is not a valid hostname character, so the parser +# consumes zero characters and returns "Empty input is invalid". +# +value ipaddr +match Empty input is invalid + +value ipaddr ! +match Empty input is invalid + +value ipv4prefix ! +match Empty input is invalid + +value ipv6addr ! +match Empty input is invalid + +value ipv6prefix ! +match Empty input is invalid + +value combo-ip ! +match Empty input is invalid + +value combo-prefix ! +match Empty input is invalid + +# +# Non-numeric input is invalid for integer types +# + +# Note end of string immediately after "uint32" +value uint32 +match empty input is invalid + +value uint8 ! +match Failed parsing string as type 'uint8' + +value uint16 ! +match Failed parsing string as type 'uint16' + +value uint32 ! +match Failed parsing string as type 'uint32' + +value uint64 ! +match Failed parsing string as type 'uint64' + +value int8 ! +match Failed parsing string as type 'int8' + +value int16 ! +match Failed parsing string as type 'int16' + +value int32 ! +match Failed parsing string as type 'int32' + +value int64 ! +match Failed parsing string as type 'int64' + +value float32 ! +match Failed parsing string as type 'float32' + +value float64 ! +match Failed parsing string as type 'float64' + +# +# Non-boolean input is invalid +# +value bool ! +match Invalid boolean value. Accepted values are "yes", "no", "true", "false" or any unquoted integer + value date Jan 1 1970 12:00:00 UTC match 1970-01-01T12:00:00Z @@ -253,4 +323,4 @@ encode-dns-label www_foo.com match Invalid character 0x5f in label count -match 126 +match 164