From: Alan T. DeKok Date: Sat, 21 May 2022 14:15:44 +0000 (-0400) Subject: purify arguments, even if the function can't be purified X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8694cb34c84de86f96f857a668aa76b363122f96;p=thirdparty%2Ffreeradius-server.git purify arguments, even if the function can't be purified 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. --- diff --git a/src/lib/unlang/xlat_expr.c b/src/lib/unlang/xlat_expr.c index 04f13601fb5..f7ac21b2c4d 100644 --- a/src/lib/unlang/xlat_expr.c +++ b/src/lib/unlang/xlat_expr.c @@ -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; diff --git a/src/lib/unlang/xlat_purify.c b/src/lib/unlang/xlat_purify.c index c07860b507b..ffecd253144 100644 --- a/src/lib/unlang/xlat_purify.c +++ b/src/lib/unlang/xlat_purify.c @@ -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; diff --git a/src/lib/unlang/xlat_tokenize.c b/src/lib/unlang/xlat_tokenize.c index 04b47dc12ec..18f3e0a772d 100644 --- a/src/lib/unlang/xlat_tokenize.c +++ b/src/lib/unlang/xlat_tokenize.c @@ -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