]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
remove "hoist vpt->xlat into xlat" in tokenize expression
authorAlan T. DeKok <aland@freeradius.org>
Mon, 16 Oct 2023 22:10:58 +0000 (18:10 -0400)
committerAlan T. DeKok <aland@freeradius.org>
Mon, 16 Oct 2023 22:14:11 +0000 (18:14 -0400)
the hoisting would put the expansion into an XLAT_GROUP, which
meant that any output value-boxes were wrapped in a value-box
group.  Which was distinctly unexpected.

src/lib/unlang/xlat_expr.c
src/lib/unlang/xlat_purify.c
src/lib/unlang/xlat_tokenize.c
src/tests/xlat/expr.txt
src/tests/xlat/file.txt

index abf43e6b238669d534fb748c95479ede66905409..548c3959cfea68117986471d5c2b70c302fa181b 100644 (file)
@@ -2462,30 +2462,6 @@ static fr_slen_t tokenize_field(xlat_exp_head_t *head, xlat_exp_t **out, fr_sbuf
         *      Do various tmpl fixups.
         */
 
-       /*
-        *      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.
-        */
-       if (tmpl_is_xlat(vpt) || tmpl_is_xlat_unresolved(vpt)) {
-               xlat_exp_head_t *xlat = tmpl_xlat(vpt);
-               xlat_exp_t      *arg = NULL;
-
-               XLAT_HEAD_VERIFY(xlat);
-
-               MEM(arg = xlat_exp_alloc(head, XLAT_GROUP, vpt->name, strlen(vpt->name)));
-
-               talloc_steal(arg->group, xlat);
-               arg->group = xlat;
-               arg->quote = quote;
-               arg->flags = xlat->flags;
-
-               talloc_free(node);      /* also frees tmpl, leaving just the xlat */
-               node = arg;
-
-               goto done;
-       }
-
        /*
         *      Try and add any unknown attributes to the dictionary immediately.  This means any future
         *      references will all point to the same da.
@@ -2520,7 +2496,16 @@ static fr_slen_t tokenize_field(xlat_exp_head_t *head, xlat_exp_t **out, fr_sbuf
        node->quote = quote;
        xlat_exp_set_name_buffer_shallow(node, vpt->name);
 
-       node->flags.pure = tmpl_is_data(node->vpt);
+       if (tmpl_is_data(node->vpt)) {
+                       node->flags.pure = true;
+
+       } else if (tmpl_contains_xlat(node->vpt)) {
+               node->flags = tmpl_xlat(vpt)->flags;
+
+       } else {
+               node->flags.pure = false;
+       }
+
        node->flags.constant = node->flags.pure;
        node->flags.needs_resolving = tmpl_needs_resolving(node->vpt);
 
index fd297fe6fb0273e214bfd380598b7ac0a111b3fb..0f7e20b47a43201ff4ade2de694891c9a3bd70ed 100644 (file)
@@ -77,6 +77,18 @@ int xlat_purify_list(xlat_exp_head_t *head, request_t *request)
                if (!node->flags.can_purify) continue;
 
                switch (node->type) {
+               case XLAT_TMPL:
+                       if (tmpl_is_xlat(node->vpt)) {
+                               xlat_exp_head_t *child = tmpl_xlat(node->vpt);
+
+                               rcode = xlat_purify_list(child, request);
+                               if (rcode < 0) return rcode;
+
+                               node->flags = child->flags;
+                               break;
+                       }
+                       FALL_THROUGH;
+
                default:
                        fr_strerror_printf("Internal error - cannot purify xlat");
                        return -1;
index 256dc4ae9e8b3b06f0a2fb1c3b3b586a0700d87f..e1ceb6214e647f84dd813381d00677c1e642029d 100644 (file)
@@ -1486,15 +1486,14 @@ ssize_t xlat_print_node(fr_sbuff_t *out, xlat_exp_head_t const *head, xlat_exp_t
                        goto done;
                }
 
-               if (tmpl_is_xlat(node->vpt)) {
-                       xlat_print(out, tmpl_xlat(node->vpt), fr_value_escape_by_quote[node->quote]);
-                       goto done;
-               }
-
-               if (tmpl_contains_xlat(node->vpt)) { /* exec */
-                       FR_SBUFF_IN_CHAR_RETURN(out, fr_token_quote[node->vpt->quote]);
-                       xlat_print(out, tmpl_xlat(node->vpt), fr_value_escape_by_quote[node->quote]);
-                       FR_SBUFF_IN_CHAR_RETURN(out, fr_token_quote[node->vpt->quote]);
+               if (tmpl_contains_xlat(node->vpt)) { /* xlat and exec */
+                       if (node->vpt->quote == T_BARE_WORD) {
+                               xlat_print(out, tmpl_xlat(node->vpt), NULL);
+                       } else {
+                               FR_SBUFF_IN_CHAR_RETURN(out, fr_token_quote[node->vpt->quote]);
+                               xlat_print(out, tmpl_xlat(node->vpt), fr_value_escape_by_quote[node->quote]);
+                               FR_SBUFF_IN_CHAR_RETURN(out, fr_token_quote[node->vpt->quote]);
+                       }
                        goto done;
                }
 
index d5a5137347679830720615509753f8e80ad28cc2..7666387e6b94eba3cdb753160a7391a9ca1aed14 100644 (file)
@@ -35,7 +35,7 @@ xlat_expr (uint32) 1 << 31
 match 2147483648
 
 xlat_expr %n
-match {0}
+match 0
 
 xlat_expr &Net.Src.IP =~ /^127.0/
 match true
@@ -122,7 +122,7 @@ match foo baz bar
 #  The User-Name has to exist
 #
 xlat_expr %{User-Name}
-match {bob}
+match bob
 
 #
 #  We're not hashing the string value of the attribute reference
index 9bbd91945c01a9e3ddc5a54e068bffc43a6764ee..4a7e33802aa811fb87a43e640e536c3e63bca136 100644 (file)
@@ -1,29 +1,35 @@
 xlat_expr %file.head('src/tests/xlat/file/one')
-match {foo}
+match foo
 
 #
 #  No LF at the end of the line
 #
 xlat_expr %file.head('src/tests/xlat/file/one-no-lf')
-match {foo}
+match foo
 
 xlat_expr %file.head('src/tests/xlat/file/two')
-match {foo bar}
+match foo bar
 
 xlat_expr %file.tail('src/tests/xlat/file/two')
-match {baz is good}
+match baz is good
 
 xlat_expr %file.tail('src/tests/xlat/file/two-no-lf')
-match {baz is good}
+match baz is good
 
 xlat_expr %file.tail('src/tests/xlat/file/three')
-match {but it was good}
+match but it was good
 
 xlat_expr %file.tail('src/tests/xlat/file/three', 1)
-match {but it was good}
+match but it was good
 
 xlat_expr %file.tail('src/tests/xlat/file/three', 2)
-match {who was very baaad\012but it was good}
+match who was very baaad\012but it was good
 
 xlat_expr %file.size('src/tests/xlat/file/three')
-match {64}
+match 64
+
+xlat_expr %file.exists('src/tests/xlat/file/three')
+match yes
+
+xlat_expr %file.exists('src/tests/xlat/file/no-such-file')
+match no