From: Alan T. DeKok Date: Fri, 3 Jun 2022 12:18:54 +0000 (-0400) Subject: add fr_value_box_is_truthy() function X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=db9a4fac2491596584dd858796e387c49b01a457;p=thirdparty%2Ffreeradius-server.git add fr_value_box_is_truthy() function as "cast to bool" will parse "yes / no" for strings into true / false booleans. Instead for conditions, we want zero-length strings to be false, and non-zero length strings to be true. --- diff --git a/src/lib/unlang/xlat_expr.c b/src/lib/unlang/xlat_expr.c index 9e18ab1ccb5..f2f85050713 100644 --- a/src/lib/unlang/xlat_expr.c +++ b/src/lib/unlang/xlat_expr.c @@ -595,48 +595,6 @@ static xlat_action_t xlat_func_ ## _name(TALLOC_CTX *ctx, fr_dcursor_t *out, \ XLAT_REGEX_FUNC(reg_eq, T_OP_REG_EQ) XLAT_REGEX_FUNC(reg_ne, T_OP_REG_NE) -/** Check truthiness of values. - * - * The casting rules for expressions / conditions are slightly - * different than fr_value_box_cast(). Largely because that - * function is used to parse configuration files, and parses "yes - * / no" and "true / false" strings, even if there's no - * fr_dict_attr_t passed to it. - */ -static bool truthiness(fr_value_box_t const *in) -{ - fr_value_box_t box; - - switch (in->type) { - case FR_TYPE_NULL: - return false; - - case FR_TYPE_STRUCTURAL: - if (in->type == FR_TYPE_GROUP) return (fr_value_box_list_len(&in->vb_group) > 0); - return false; - - case FR_TYPE_BOOL: - return in->vb_bool; - - case FR_TYPE_STRING: - case FR_TYPE_OCTETS: - return (in->vb_length > 0); - - case FR_TYPE_IPV4_ADDR: - case FR_TYPE_IPV6_ADDR: - return !fr_ipaddr_is_inaddr_any(&in->vb_ip); - - case FR_TYPE_IPV4_PREFIX: - case FR_TYPE_IPV6_PREFIX: - return !((in->vb_ip.prefix == 0) && fr_ipaddr_is_inaddr_any(&in->vb_ip)); - - default: - fr_value_box_init_null(&box); - (void) fr_value_box_cast(NULL, &box, FR_TYPE_BOOL, NULL, in); - return box.vb_bool; - } -} - typedef struct { bool stop; int argc; @@ -745,7 +703,7 @@ check: * * On "false", omit this argument, and go to the next one. */ - *result = (truthiness(box) == sense); + *result = (fr_value_box_is_truthy(box) == sense); if (!*result) return true; @@ -930,7 +888,7 @@ static bool xlat_logical_match(fr_value_box_t **dst, fr_value_box_list_t const * } if (logical_or) { - if (truthiness(box)) { + if (fr_value_box_is_truthy(box)) { DEBUG("True || %pV", box); last = box; /* stop at the first matching one, and return it. */ break; @@ -943,7 +901,7 @@ static bool xlat_logical_match(fr_value_box_t **dst, fr_value_box_list_t const * /* * Must be logical && */ - if (truthiness(box)) { + if (fr_value_box_is_truthy(box)) { DEBUG("True && %pV", box); last = box; continue; diff --git a/src/lib/util/value.c b/src/lib/util/value.c index 22b38071362..e9a40d17f99 100644 --- a/src/lib/util/value.c +++ b/src/lib/util/value.c @@ -5877,3 +5877,45 @@ void fr_value_box_mark_unsafe(fr_value_box_t *box) { box->safe = 0; } + +/** Check truthiness of values. + * + * The casting rules for expressions / conditions are slightly + * different than fr_value_box_cast(). Largely because that + * function is used to parse configuration files, and parses "yes + * / no" and "true / false" strings, even if there's no + * fr_dict_attr_t passed to it. + */ +bool fr_value_box_is_truthy(fr_value_box_t const *in) +{ + fr_value_box_t box; + + switch (in->type) { + case FR_TYPE_NULL: + return false; + + case FR_TYPE_STRUCTURAL: + if (in->type == FR_TYPE_GROUP) return (fr_value_box_list_len(&in->vb_group) > 0); + return false; + + case FR_TYPE_BOOL: + return in->vb_bool; + + case FR_TYPE_STRING: + case FR_TYPE_OCTETS: + return (in->vb_length > 0); + + case FR_TYPE_IPV4_ADDR: + case FR_TYPE_IPV6_ADDR: + return !fr_ipaddr_is_inaddr_any(&in->vb_ip); + + case FR_TYPE_IPV4_PREFIX: + case FR_TYPE_IPV6_PREFIX: + return !((in->vb_ip.prefix == 0) && fr_ipaddr_is_inaddr_any(&in->vb_ip)); + + default: + fr_value_box_init_null(&box); + (void) fr_value_box_cast(NULL, &box, FR_TYPE_BOOL, NULL, in); + return box.vb_bool; + } +} diff --git a/src/lib/util/value.h b/src/lib/util/value.h index 85cb8bfff9f..23300077eea 100644 --- a/src/lib/util/value.h +++ b/src/lib/util/value.h @@ -780,6 +780,9 @@ int fr_value_box_cast_in_place(TALLOC_CTX *ctx, fr_value_box_t *vb, fr_type_t dst_type, fr_dict_attr_t const *dst_enumv) CC_HINT(nonnull(1)); +bool fr_value_box_is_truthy(fr_value_box_t const *box) + CC_HINT(nonnull(1)); + int fr_value_box_ipaddr(fr_value_box_t *dst, fr_dict_attr_t const *enumv, fr_ipaddr_t const *ipaddr, bool tainted) CC_HINT(nonnull(1,3));