]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
hoist casts when hoisting xlats
authorAlan T. DeKok <aland@freeradius.org>
Thu, 23 Jun 2022 19:50:38 +0000 (15:50 -0400)
committerAlan T. DeKok <aland@freeradius.org>
Tue, 28 Jun 2022 00:22:09 +0000 (20:22 -0400)
and update tests which now have casts all over the place

src/lib/unlang/xlat_expr.c
src/lib/unlang/xlat_purify.c
src/tests/unit/xlat/cond_base.txt
src/tests/unit/xlat/purify.txt

index 367453447246fd7d7ae78bb493537f8a9a9b0cf3..71fea972e3c2afbf290cb3cb0ebe5ad0f6ba6e8a 100644 (file)
@@ -1943,9 +1943,15 @@ static ssize_t tokenize_field(xlat_exp_head_t *head, xlat_exp_t **out, fr_sbuff_
         *      Don't keep an intermediate tmpl for xlats.  Just hoist
         *      the xlat to be a child of this node. Exec and regexes
         *      are left alone, as they are handled by different code.
+        *
+        *      However, we also add a cast if the tmpl had a cast.
+        *      And if there was no cast, but the input was a string,
+        *      then we cast the result to a string, too.
         */
        if (tmpl_contains_xlat(vpt) && !tmpl_is_exec(vpt) && !tmpl_contains_regex(vpt)) {
                xlat_exp_head_t *xlat = tmpl_xlat(vpt);
+               xlat_exp_t *cast;
+               fr_type_t type;
 
                talloc_steal(node, xlat);
                node->fmt = talloc_typed_strdup(node, node->fmt);
@@ -1957,6 +1963,19 @@ static ssize_t tokenize_field(xlat_exp_head_t *head, xlat_exp_t **out, fr_sbuff_
 
                node->flags = xlat->flags;
 
+               if (quote != T_BARE_WORD) {
+                       if (tmpl_rules_cast(vpt) != FR_TYPE_NULL) {
+                               type = tmpl_rules_cast(vpt);
+                       } else {
+                               type = FR_TYPE_STRING;
+                       }
+
+                       MEM(cast = expr_cast_alloc(head, type));
+
+                       xlat_func_append_arg(cast, node);
+                       node = cast;
+               }
+
        } else {
                /*
                 *      Else we're not hoisting, set the node to the VPT
index 7fd44156e95fc7c409c96c87465a7b5c8139343c..aa8d194eccdde5f498592f1cf449e93103769cb4 100644 (file)
@@ -42,7 +42,7 @@ static void xlat_value_list_to_xlat(xlat_exp_head_t *head, fr_value_box_list_t *
                talloc_free(box);
 
                if (node->data.type == FR_TYPE_STRING) {
-                       node->quote = T_SINGLE_QUOTED_STRING;
+                       node->quote = T_DOUBLE_QUOTED_STRING;
                        node->fmt = node->data.vb_strvalue;
                } else {
                        node->quote = T_BARE_WORD;
index 59c4914c5ab49daecb97a7ed1b857e0d3fed8bfc..e553022481de84d44c6c8d007ff6d7df43333b96 100644 (file)
@@ -90,6 +90,9 @@ match ((&User-Name == &User-Password) || (&Filter-Id == &Reply-Message))
 xlat_purify (!(&User-Name == &User-Password) || (&Filter-Id == &Reply-Message))
 match (!(&User-Name == &User-Password) || (&Filter-Id == &Reply-Message))
 
+#xlat_purify (!&User-Name == &User-Password || &Filter-Id == &Reply-Message)
+#match (!(&User-Name == &User-Password) || (&Filter-Id == &Reply-Message))
+
 #  different from the previous ones.
 xlat_purify (!((&User-Name == &User-Password) || (&Filter-Id == &Reply-Message)))
 match !((&User-Name == &User-Password) || (&Filter-Id == &Reply-Message))
@@ -221,7 +224,7 @@ match (&Session-Timeout == '10')
 #  @todo - yuck.  Suppress full path?
 #
 xlat_purify &Event-Timestamp == "January 1, 2012 %{User-Name}"
-match (&Event-Timestamp == "January 1, 2012 %{Request[0].User-Name}")
+match (&Event-Timestamp == %(cast:string "January 1, 2012 %{Request[0].User-Name}"))
 
 # This one is NOT an expansion, so it's parsed into normal form
 xlat_purify &Event-Timestamp == 'January 1 2012'
@@ -310,18 +313,13 @@ xlat_purify ('foo' == 'foo')
 match true
 
 #
-#  @todo - if the types are incompatible, what to do?
+#  MD4 hash is not equal to other things
 #
-# Cannot compare incompatible types
 xlat_purify ("foo" == "%{md4: foo}")
-match NULL
+match false
 
-#
-#  @todo - maybe we just want to allow this?
-#
-# Cannot compare incompatible types
 xlat_purify ("foo bar" == "%{md4: foo}")
-match NULL
+match false
 
 xlat_purify ("foo" == "bar")
 match false
@@ -337,8 +335,14 @@ match false
 xlat_purify (&User-Name == "bob")
 match (&User-Name == "bob")
 
+xlat_purify (&User-Name == %{md4: blah})
+match (&User-Name == 0x544924d05ec4481925ba3749a096a0a7)
+
+xlat_purify (&User-Name == (string) %{md4: blah})
+match (&User-Name == 0x544924d05ec4481925ba3749a096a0a7)
+
 xlat_purify (&User-Name == "%{md4: blah}")
-match (&User-Name == "0x544924d05ec4481925ba3749a096a0a7")
+match (&User-Name == "TI$\320^\304H\031\%\2727I\240\226\240\247")
 
 xlat_purify <ipaddr>127.0.0.1 == 2130706433
 match true
@@ -430,8 +434,13 @@ match ("foo" == &User-Name)
 
 # This used to be expr, but expr isn't a builtin, so it failed...
 
+#
+#  @todo - arguably this is a failed thing, we should get:
+#
+#  ERROR: Failed casting 0x002ade8665c69219ca16bd108d92c8d5 to data type uint32: Invalid cast from octets to uint32.  Source length 16 is greater than destination type size 4
+#
 xlat_purify <integer>"%{md4: 1 + 1}" < &NAS-Port
-match ("0x002ade8665c69219ca16bd108d92c8d5" < &NAS-Port)
+match (%(cast:uint32 "%{md4: 1 + 1}") < &NAS-Port)
 
 #
 #  The string gets parsed as an IP address.
@@ -464,7 +473,7 @@ match ((ipaddr)&PMIP6-Home-IPv4-HoA == &Framed-IP-Address)
 
 # but these are allowed
 xlat_purify <ether>&Tmp-uint64-0 == "%{module: foo}"
-match  ((ether)&Tmp-uint64-0 == "%{module: foo}")
+match  ((ether)&Tmp-uint64-0 == %(cast:string "%{module: foo}"))
 
 xlat_purify <ipaddr>&Filter-Id == &Framed-IP-Address
 match ((ipaddr)&Filter-Id == &Framed-IP-Address)
@@ -493,7 +502,7 @@ match (&User-Name[n] == "bob")
 #match &Foo-Bar
 
 xlat_purify &Acct-Input-Octets > "%{Session-Timeout}"
-match (&Acct-Input-Octets > "%{Request[0].Session-Timeout}")
+match (&Acct-Input-Octets > %(cast:string "%{Request[0].Session-Timeout}"))
 
 xlat_purify &Acct-Input-Octets > &Session-Timeout
 match (&Acct-Input-Octets > &Session-Timeout)
@@ -732,4 +741,4 @@ match %{rcode:'handled'}
 
 
 count
-match 300
+match 304
index fec1407871a8edf631fc2d53d17af4fe37003911..d3e8b8c497e76c02fa0409af2a3b836855aa6f85 100644 (file)
@@ -166,7 +166,7 @@ match (&Reply-Message == "foo")
 #  Strings are single quoted
 #
 xlat_purify &Filter-Id == ("foo" + "bar")
-match (&Filter-Id == 'foobar')
+match (&Filter-Id == "foobar")
 
 xlat_purify !&User-Name
 match !&User-Name