]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
purify arguments, even if the function can't be purified
authorAlan T. DeKok <aland@freeradius.org>
Sat, 21 May 2022 14:15:44 +0000 (10:15 -0400)
committerAlan T. DeKok <aland@freeradius.org>
Sat, 21 May 2022 14:28:42 +0000 (10:28 -0400)
and hoist can_purify up to the parent.

We should really have a merge flags just for XLAT_FUNC, which
would cut down on some of this repetition.

src/lib/unlang/xlat_expr.c
src/lib/unlang/xlat_purify.c
src/lib/unlang/xlat_tokenize.c

index 04f13601fb598a1029cba81acb077b6dc1eaccb1..f7ac21b2c4dcceaf91e4bcc8c28f0361fab869b8 100644 (file)
@@ -803,7 +803,7 @@ static ssize_t tokenize_unary(xlat_exp_head_t *head, xlat_exp_t **out, fr_sbuff_
 
        xlat_exp_insert_tail(unary->call.args, node);
        xlat_flags_merge(&unary->flags, &unary->call.args->flags);
-       unary->flags.can_purify = unary->call.func->flags.pure && unary->call.args->flags.pure;
+       unary->flags.can_purify = (unary->call.func->flags.pure && unary->call.args->flags.pure) | unary->call.args->flags.can_purify;
 
        /*
         *      Don't add it to head->flags, that will be done when it's actually inserted.
@@ -1207,7 +1207,7 @@ redo:
 
        fr_assert(xlat_exp_head(node->call.args) != NULL);
 
-       node->flags.can_purify = node->call.func->flags.pure && node->call.args->flags.pure;
+       node->flags.can_purify = (node->call.func->flags.pure && node->call.args->flags.pure) | node->call.args->flags.can_purify;
 
        lhs = node;
        goto redo;
index c07860b507b08cfda94761756b0d04f2b77c83c4..ffecd253144edbed8e804aabfa1de4b95fed5573 100644 (file)
@@ -97,6 +97,13 @@ static int xlat_purify_list(xlat_exp_head_t *head, request_t *request)
                        break;
                        
                case XLAT_FUNC:
+                       if (!node->flags.pure && node->flags.can_purify) {
+                               if (xlat_purify_list(node->call.args, request) < 0) return -1;
+                               break;
+                       }
+
+                       fr_assert(node->flags.pure);
+
                        fr_value_box_list_init(&list);
                        if (unlang_xlat_push_node(node->call.args, &success, &list, request, node) < 0) {
                                return -1;
index 04b47dc12ecc317f309947a5aed0ae0f916b4561..18f3e0a772df214b6bcf23862949d3cfc7932b10 100644 (file)
@@ -132,7 +132,7 @@ xlat_exp_t *xlat_exp_func_alloc(TALLOC_CTX *ctx, xlat_t *func, xlat_exp_head_t c
         *      If the function is pure, AND it's arguments are pure,
         *      then remember that we need to call a pure function.
         */
-       node->flags.can_purify = func->flags.pure && args->flags.pure;
+       node->flags.can_purify = (func->flags.pure && args->flags.pure) | args->flags.can_purify;
 
        return node;
 }
@@ -507,7 +507,7 @@ int xlat_tokenize_function_args(xlat_exp_head_t *head, fr_sbuff_t *in,
        if (node->type == XLAT_FUNC) {
                if (xlat_validate_function_args(node) < 0) goto error;
 
-               node->flags.can_purify = node->call.func->flags.pure && node->call.args->flags.pure;
+               node->flags.can_purify = (node->call.func->flags.pure && node->call.args->flags.pure) | node->call.args->flags.can_purify;
        }
 
        if (!fr_sbuff_next_if_char(in, ')')) {
@@ -1660,7 +1660,7 @@ int xlat_resolve(xlat_exp_head_t *head, xlat_res_rules_t const *xr_rules)
                        node->flags = node->call.func->flags;
                        xlat_flags_merge(&node->flags, &node->call.args->flags);
 
-                       node->flags.can_purify = node->call.func->flags.pure && node->call.args->flags.pure;
+                       node->flags.can_purify = (node->call.func->flags.pure && node->call.args->flags.pure) | node->call.args->flags.can_purify;
                        break;
 
                /*
@@ -1734,7 +1734,7 @@ int xlat_resolve(xlat_exp_head_t *head, xlat_res_rules_t const *xr_rules)
                         */
                        xlat_flags_merge(&node->flags, &node->call.args->flags);
 
-                       node->flags.can_purify = node->call.func->flags.pure && node->call.args->flags.pure;
+                       node->flags.can_purify = (node->call.func->flags.pure && node->call.args->flags.pure) | node->call.args->flags.can_purify;
 
                        /*
                         *      Add the freshly resolved function