]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
allow comparisons to print "true" and "false"
authorAlan T. DeKok <aland@freeradius.org>
Thu, 26 May 2022 18:14:54 +0000 (14:14 -0400)
committerAlan T. DeKok <aland@freeradius.org>
Fri, 3 Jun 2022 11:15:41 +0000 (07:15 -0400)
instead of "yes" and "no".

this doesn't *always* work.  A bare

(bool) true

will result in a box of FR_TYPE_BOOL, with no enumv, and will thus
print as "yes".  But we blame value.c for that.

share/dictionary/freeradius/dictionary.freeradius.internal
src/lib/unlang/xlat_eval.c
src/lib/unlang/xlat_expr.c
src/lib/unlang/xlat_priv.h
src/tests/unit/xlat/cond_base.txt
src/tests/unit/xlat/purify.txt

index f11c08d1ebdc45ca03c64d953d46a5656776b32e..96fd37e01be0c4aa8b223145af3aeb7282460427 100644 (file)
@@ -357,10 +357,6 @@ ATTRIBUTE  Tmp-Date-7                              1757    date
 ATTRIBUTE      Tmp-Date-8                              1758    date
 ATTRIBUTE      Tmp-Date-9                              1759    date
 
-#
-#  Attributes 1850 through 1850 + FR_TYPE_MAX are reserved.
-#
-
 ATTRIBUTE      Tmp-uint64-0                            1760    uint64
 ATTRIBUTE      Tmp-uint64-1                            1761    uint64
 ATTRIBUTE      Tmp-uint64-2                            1762    uint64
@@ -399,8 +395,27 @@ ATTRIBUTE  Tmp-Ethernet-1                          1791    ether
 ATTRIBUTE      Tmp-Ethernet-2                          1792    ether
 ATTRIBUTE      Tmp-Ethernet-3                          1793    ether
 ATTRIBUTE      Tmp-Ethernet-4                          1794    ether
+ATTRIBUTE      Tmp-Ethernet-5                          1795    ether
+ATTRIBUTE      Tmp-Ethernet-6                          1796    ether
+ATTRIBUTE      Tmp-Ethernet-7                          1797    ether
+ATTRIBUTE      Tmp-Ethernet-8                          1798    ether
+ATTRIBUTE      Tmp-Ethernet-9                          1799    ether
 
 ATTRIBUTE      Tmp-Float-0                             1880    float32
+ATTRIBUTE      Tmp-Float-1                             1881    float32
+ATTRIBUTE      Tmp-Float-2                             1882    float32
+ATTRIBUTE      Tmp-Float-3                             1883    float32
+ATTRIBUTE      Tmp-Float-4                             1884    float32
+ATTRIBUTE      Tmp-Float-5                             1885    float32
+ATTRIBUTE      Tmp-Float-6                             1886    float32
+ATTRIBUTE      Tmp-Float-7                             1887    float32
+ATTRIBUTE      Tmp-Float-8                             1888    float32
+ATTRIBUTE      Tmp-Float-9                             1889    float32
+
+#  Used by xlat expressions to print true/false instead of yes/no
+ATTRIBUTE      Expr-Bool-Enum                          1890    bool
+VALUE  Expr-Bool-Enum                  true                    1
+VALUE  Expr-Bool-Enum                  false                   0
 
 ATTRIBUTE      Log-Message                             1894    string
 ATTRIBUTE      Log-Level                               1895    integer
index ab6b01eee44d4430ad8de39e2df6f304cad2f53c..f87f5575fbc95d2565ffe1fbd68aa5276c3e392e 100644 (file)
@@ -60,7 +60,7 @@ static fr_dict_attr_t const *attr_virtual_server;
 
 static fr_dict_attr_t const *attr_packet_authentication_vector;
 static fr_dict_attr_t const *attr_packet_type;
-fr_dict_attr_t const       *attr_cast_base; /* for xlat_expr.c */
+fr_dict_attr_t const       *attr_expr_bool_enum; /* xlat_expr.c */
 
 static fr_dict_attr_autoload_t xlat_eval_dict_attr[] = {
        { .out = &attr_client_ip_address, .name = "Client-IP-Address", .type = FR_TYPE_IPV4_ADDR, .dict = &dict_freeradius },
@@ -77,7 +77,7 @@ static fr_dict_attr_autoload_t xlat_eval_dict_attr[] = {
 
        { .out = &attr_packet_authentication_vector, .name = "Packet-Authentication-Vector", .type = FR_TYPE_OCTETS, .dict = &dict_radius },
        { .out = &attr_packet_type, .name = "Packet-Type", .type = FR_TYPE_UINT32, .dict = &dict_radius },
-       { .out = &attr_cast_base, .name = "Cast-Base", .type = FR_TYPE_UINT8, .dict = &dict_freeradius },
+       { .out = &attr_expr_bool_enum, .name = "Expr-Bool-Enum", .type = FR_TYPE_BOOL, .dict = &dict_freeradius },
        { NULL }
 };
 
index da8a6e39b62a72a14dee96123c5340e393cb9405..c18a454e6611fa30eec9f9b7d68a79b350847595 100644 (file)
@@ -236,7 +236,8 @@ static xlat_arg_parser_t const binary_op_xlat_args[] = {
 static xlat_action_t xlat_binary_op(TALLOC_CTX *ctx, fr_dcursor_t *out,
                                    UNUSED xlat_ctx_t const *xctx,
                                    request_t *request, fr_value_box_list_t *in,
-                                   fr_token_t op)
+                                   fr_token_t op,
+                                   fr_type_t default_type, fr_dict_attr_t const *enumv)
 {
        int rcode;
        fr_value_box_t  *dst, *a, *b;
@@ -272,7 +273,7 @@ static xlat_action_t xlat_binary_op(TALLOC_CTX *ctx, fr_dcursor_t *out,
                return XLAT_ACTION_FAIL;
        }
 
-       rcode = fr_value_calc_binary_op(dst, dst, FR_TYPE_NULL,
+       rcode = fr_value_calc_binary_op(dst, dst, default_type,
                                        fr_dlist_head(&a->vb_group),
                                        op,
                                        fr_dlist_head(&b->vb_group));
@@ -281,6 +282,12 @@ static xlat_action_t xlat_binary_op(TALLOC_CTX *ctx, fr_dcursor_t *out,
                return XLAT_ACTION_FAIL;
        }
 
+       /*
+        *      Over-write, but only if it's present.  Otherwise leave
+        *      any existing enum alone.
+        */
+       if (enumv) dst->enumv = enumv;
+
        fr_dcursor_append(out, dst);
        return XLAT_ACTION_DONE;
 }
@@ -290,7 +297,7 @@ static xlat_action_t xlat_func_ ## _name(TALLOC_CTX *ctx, fr_dcursor_t *out, \
                                   xlat_ctx_t const *xctx, \
                                   request_t *request, fr_value_box_list_t *in)  \
 { \
-       return xlat_binary_op(ctx, out, xctx, request, in, _op); \
+       return xlat_binary_op(ctx, out, xctx, request, in, _op, FR_TYPE_NULL, NULL); \
 }
 
 XLAT_BINARY_FUNC(op_add, T_ADD)
@@ -303,12 +310,20 @@ XLAT_BINARY_FUNC(op_xor,  T_XOR)
 XLAT_BINARY_FUNC(op_rshift, T_RSHIFT)
 XLAT_BINARY_FUNC(op_lshift, T_LSHIFT)
 
-XLAT_BINARY_FUNC(cmp_eq,  T_OP_CMP_EQ)
-XLAT_BINARY_FUNC(cmp_ne,  T_OP_NE)
-XLAT_BINARY_FUNC(cmp_lt,  T_OP_LT)
-XLAT_BINARY_FUNC(cmp_le,  T_OP_LE)
-XLAT_BINARY_FUNC(cmp_gt,  T_OP_GT)
-XLAT_BINARY_FUNC(cmp_ge,  T_OP_GE)
+#define XLAT_CMP_FUNC(_name, _op)  \
+static xlat_action_t xlat_func_ ## _name(TALLOC_CTX *ctx, fr_dcursor_t *out, \
+                                  xlat_ctx_t const *xctx, \
+                                  request_t *request, fr_value_box_list_t *in)  \
+{ \
+       return xlat_binary_op(ctx, out, xctx, request, in, _op, FR_TYPE_BOOL, attr_expr_bool_enum); \
+}
+
+XLAT_CMP_FUNC(cmp_eq,  T_OP_CMP_EQ)
+XLAT_CMP_FUNC(cmp_ne,  T_OP_NE)
+XLAT_CMP_FUNC(cmp_lt,  T_OP_LT)
+XLAT_CMP_FUNC(cmp_le,  T_OP_LE)
+XLAT_CMP_FUNC(cmp_gt,  T_OP_GT)
+XLAT_CMP_FUNC(cmp_ge,  T_OP_GE)
 
 /*
  *     Cast to bool for && / ||.  The casting rules for expressions /
@@ -476,7 +491,7 @@ static xlat_action_t xlat_logical_resume(TALLOC_CTX *ctx, fr_dcursor_t *out,
         */
        if (!xlat_logical_match(&result, &rctx->list, inst->sense)) {
        done:
-               MEM(dst = fr_value_box_alloc(ctx, FR_TYPE_BOOL, NULL, false));
+               MEM(dst = fr_value_box_alloc(ctx, FR_TYPE_BOOL, attr_expr_bool_enum, false));
                dst->vb_bool = result;
                fr_dcursor_append(out, dst);
 
@@ -540,7 +555,7 @@ static xlat_action_t xlat_func_unary_not(TALLOC_CTX *ctx, fr_dcursor_t *out,
        fr_value_box_t *dst, *a;
 
        a = fr_dlist_head(in);
-       MEM(dst = fr_value_box_alloc(ctx, FR_TYPE_BOOL, NULL, a->tainted));
+       MEM(dst = fr_value_box_alloc(ctx, FR_TYPE_BOOL, attr_expr_bool_enum, a->tainted));
        dst->vb_bool = !a->vb_bool;
 
        fr_dcursor_append(out, dst);
index a80270bef0137ba7c3228cc2c911f138ad27bde4..c4d5cab4b597f3167c2ffdb407cc2ce3234e8f00 100644 (file)
@@ -301,7 +301,7 @@ xlat_t      *xlat_func_find(char const *name, ssize_t namelen);
 /*
  *     xlat_eval.c
  */
-extern fr_dict_attr_t const *attr_cast_base;
+extern fr_dict_attr_t const *attr_expr_bool_enum;
 
 void           xlat_signal(xlat_func_signal_t signal, xlat_exp_t const *exp,
                            request_t *request, void *rctx, fr_state_signal_t action);
index 8775b910d2d713291aa5b020c02462116bbb112e..b796c8b78f0b21c21e8c39a82000c894976d961c 100644 (file)
@@ -250,7 +250,7 @@ match ERROR offset 1: Failed parsing string as type 'uint32'
 #  and then statically evaluated.
 #
 xlat_purify <ipaddr>127.0.0.1 == "127.0.0.1"
-match yes
+match true
 
 #  @todo - why isn't the RHS being purified?
 xlat_purify <ipaddr>127.0.0.1 == "%{md4: 127.0.0.1}"
@@ -269,7 +269,7 @@ xlat_purify <ipaddr>127.0.0.1 == %{md4: SELECT user FROM table WHERE user='%{Use
 match (127.0.0.1 == %{md4: SELECT user FROM table WHERE user='%{Request[0].User-Name}'})
 
 xlat_purify <ether> 00:11:22:33:44:55 == "00:11:22:33:44:55"
-match yes
+match true
 
 #  @todo - why isn't the RHS being purified?
 xlat_purify <ether>00:11:22:33:44:55 == "%{md4:00:11:22:33:44:55}"
@@ -281,6 +281,7 @@ match ERROR offset 12: Missing separator, expected ':'
 #
 #  Tests for boolean data types.
 #
+# @todo - we probably want this to use "true", too.
 xlat_purify true
 match yes
 
@@ -314,22 +315,22 @@ match (yes || (&User-Name == "bob"))
 #  Both sides static data with a cast: evaluate at parse time.
 #
 xlat_purify <integer>20 < 100
-match yes
+match true
 
 #
 #  Both sides literal: evaluate at parse time
 #
 xlat_purify ('foo' == 'bar')
-match no
+match false
 
 xlat_purify ('foo' < 'bar')
-match no
+match false
 
 xlat_purify ('foo' > 'bar')
-match yes
+match true
 
 xlat_purify ('foo' == 'foo')
-match yes
+match true
 
 #
 #  @todo - why isn't the RHS being purified?
@@ -346,10 +347,10 @@ xlat_purify ("foo bar" == "%{md4: foo}")
 match ("foo bar" == "%{md4: foo}")
 
 xlat_purify ("foo" == "bar")
-match no
+match false
 
 xlat_purify ("foo" == 'bar')
-match no
+match false
 
 #
 #  The RHS gets parsed as a VPT_TYPE_DATA, which is
@@ -363,17 +364,17 @@ xlat_purify (&User-Name == "%{md4: blah}")
 match (&User-Name == "0x544924d05ec4481925ba3749a096a0a7")
 
 xlat_purify <ipaddr>127.0.0.1 == 2130706433
-match yes
+match true
 
 # /32 suffix should be trimmed for this type
 xlat_purify <ipaddr>127.0.0.1/32 == 127.0.0.1
-match yes
+match true
 
 xlat_purify <ipaddr>127.0.0.1/327 == 127.0.0.1
 match ERROR offset 9: Invalid IPv4 mask length "/327".  Should be between 0-32
 
 xlat_purify <ipaddr>127.0.0.1/32 == 127.0.0.1
-match yes
+match true
 
 xlat_purify (/foo/)
 match ERROR offset 1: Unexpected regular expression
@@ -594,7 +595,7 @@ match ERROR offset 1: Attribute 'not' not found.  Searched in: RADIUS, internal:
 #  The LHS is a string with ASCII 5C 30 30 30 inside of it vs the RHS which should contain ASCII 0.
 #
 xlat_purify ('i have scary embedded things\000 inside me' == "i have scary embedded things\000 inside me")
-match no
+match false
 
 #
 #  'Unknown' attributes which are defined in the main dictionary
@@ -657,7 +658,7 @@ match &reply
 #  and empty strings
 #
 xlat_purify ("$ENV{SOMETHING_OR_OTHER}" == '')
-match no
+match false
 
 #
 #  Attributes with a protocol namespace
@@ -670,10 +671,10 @@ match (&radius.User-Name == 'bob')
 #match &User-Name == 'bob'
 
 xlat_purify !(!(0))
-match no
+match false
 
 xlat_purify (true) && (false)
-match no
+match false
 
 #
 #  More short-circuit evaluations
index b4c25b82439b206c223d25e82d81792f11403866..420d9e456dda9f1db2f8347a0871759aa0d50569 100644 (file)
@@ -39,7 +39,7 @@ xlat_purify &Framed-IP-Address + 4
 match (&Framed-IP-Address + 4)
 
 xlat_purify 1 < 4
-match yes
+match true
 
 #
 #  There's sopme bunch of things to fix here:
@@ -60,7 +60,7 @@ xlat_purify &Filter-Id == "foo"
 match (&Filter-Id == "foo")
 
 xlat_purify "foo" == "bar"
-match no
+match false
 
 # note '/' is a prefix, not "divide by 24".
 # and a useless cast is removed
@@ -85,10 +85,10 @@ match (192.168.0.0/24 > &Framed-IP-Address)
 #  Logical && and ||
 #
 xlat_purify 1 < 2 || 4 > 3
-match yes
+match true
 
 xlat_purify 2 || (1 > 4)
-match yes
+match true
 
 xlat_purify &Filter-Id
 match &Filter-Id
@@ -117,7 +117,7 @@ match 13
 #  useless casts are omitted.
 #
 xlat_purify 1 < (uint32) 2
-match yes
+match true
 
 #
 #  @todo - for exec, xlat, etc., if we're doing an existence check of
@@ -129,7 +129,7 @@ match yes
 #  This should likely be a parse error at boot time?
 #
 xlat_purify 1 < 2 < 3
-match yes
+match true
 
 xlat_purify &Service-Type == 1
 match (&Service-Type == 1)
@@ -153,13 +153,13 @@ xlat_purify !&User-Name
 match !&User-Name
 
 xlat_purify (1 < 2)
-match yes
+match true
 
 xlat_purify !(1 < 2)
-match no
+match false
 
 xlat_purify !true
-match no
+match false
 
 count
 match 69