From: Alan T. DeKok Date: Sat, 7 Oct 2023 14:49:35 +0000 (-0400) Subject: get rid of tokenize_ephemeral_expression() X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9149bda78555f0700b6baeccedfb243a5badb26d;p=thirdparty%2Ffreeradius-server.git get rid of tokenize_ephemeral_expression() and just rely on t_rules->xlat.runtime_el --- diff --git a/src/bin/unit_test_attribute.c b/src/bin/unit_test_attribute.c index af58154b98..e48125ff3a 100644 --- a/src/bin/unit_test_attribute.c +++ b/src/bin/unit_test_attribute.c @@ -2819,22 +2819,24 @@ static size_t command_xlat_purify(command_result_t *result, command_file_ctx_t * ssize_t dec_len; xlat_exp_head_t *head = NULL; size_t input_len = strlen(in), escaped_len; - - if (!el) { - fr_strerror_const("Flag '-p' not used. xlat_purify is disabled"); - goto return_error; - } - - dec_len = xlat_tokenize_ephemeral_expression(cc->tmp_ctx, &head, el, &FR_SBUFF_IN(in, input_len), NULL, - &(tmpl_rules_t) { + tmpl_rules_t t_rules = (tmpl_rules_t) { .attr = { - .dict_def = cc->tmpl_rules.attr.dict_def ? + .dict_def = cc->tmpl_rules.attr.dict_def ? cc->tmpl_rules.attr.dict_def : cc->config->dict, .allow_unresolved = cc->tmpl_rules.attr.allow_unresolved, .list_def = request_attr_request, }, .xlat = cc->tmpl_rules.xlat, - }); + .at_runtime = true, + }; + + if (!el) { + fr_strerror_const("Flag '-p' not used. xlat_purify is disabled"); + goto return_error; + } + t_rules.xlat.runtime_el = el; + + dec_len = xlat_tokenize_expression(cc->tmp_ctx, &head, &FR_SBUFF_IN(in, input_len), NULL, &t_rules); if (dec_len <= 0) { fr_strerror_printf_push_head("ERROR offset %d", (int) -dec_len); diff --git a/src/bin/unit_test_module.c b/src/bin/unit_test_module.c index e8c7b49bd5..647fe3abdd 100644 --- a/src/bin/unit_test_module.c +++ b/src/bin/unit_test_module.c @@ -494,17 +494,20 @@ static bool do_xlats(fr_event_list_t *el, request_t *request, char const *filena TALLOC_CTX *xlat_ctx = talloc_init_const("xlat"); xlat_exp_head_t *head = NULL; - slen = xlat_tokenize_ephemeral_expression(xlat_ctx, &head, el, - &line, - NULL, - &(tmpl_rules_t) { - .attr = { - .dict_def = dict_protocol, - .list_def = request_attr_request, - .allow_unresolved = true, - } - } - ); + slen = xlat_tokenize_expression(xlat_ctx, &head, + &line, + NULL, + &(tmpl_rules_t) { + .attr = { + .dict_def = dict_protocol, + .list_def = request_attr_request, + .allow_unresolved = true, + }, + .xlat = { + .runtime_el = el, + }, + .at_runtime = true, + }); if (slen <= 0) { talloc_free(xlat_ctx); fr_sbuff_in_sprintf(&out, "ERROR offset %d '%s'", (int) -slen, fr_strerror()); diff --git a/src/lib/unlang/xlat.h b/src/lib/unlang/xlat.h index 573285fb91..e9d2cfd77a 100644 --- a/src/lib/unlang/xlat.h +++ b/src/lib/unlang/xlat.h @@ -392,11 +392,6 @@ fr_slen_t xlat_tokenize_expression(TALLOC_CTX *ctx, xlat_exp_head_t **head, fr_s fr_slen_t xlat_tokenize_condition(TALLOC_CTX *ctx, xlat_exp_head_t **head, fr_sbuff_t *in, fr_sbuff_parse_rules_t const *p_rules, tmpl_rules_t const *t_rules); -fr_slen_t xlat_tokenize_ephemeral_expression(TALLOC_CTX *ctx, xlat_exp_head_t **head, - fr_event_list_t *el, - fr_sbuff_t *in, - fr_sbuff_parse_rules_t const *p_rules, tmpl_rules_t const *t_rules); - fr_slen_t xlat_tokenize_ephemeral(TALLOC_CTX *ctx, xlat_exp_head_t **head, fr_event_list_t *el, fr_sbuff_t *in, fr_sbuff_parse_rules_t const *p_rules, tmpl_rules_t const *t_rules); diff --git a/src/lib/unlang/xlat_builtin.c b/src/lib/unlang/xlat_builtin.c index 6c25430a15..f61bf47832 100644 --- a/src/lib/unlang/xlat_builtin.c +++ b/src/lib/unlang/xlat_builtin.c @@ -939,22 +939,26 @@ static xlat_action_t xlat_func_expr(TALLOC_CTX *ctx, fr_dcursor_t *out, /* * Parse the input as an expression. */ - if (xlat_tokenize_ephemeral_expression(rctx, - &rctx->ex, unlang_interpret_event_list(request), - &FR_SBUFF_IN(arg->vb_strvalue, arg->vb_length), - &(fr_sbuff_parse_rules_t){ - .escapes = &escape_rules - }, - &(tmpl_rules_t){ - .attr = { - .dict_def = request->dict, - .list_def = request_attr_request, - .allow_unknown = false, - .allow_unresolved = false, - .allow_foreign = false, - }, - .at_runtime = true - }) < 0) { + if (xlat_tokenize_expression(rctx, + &rctx->ex, + &FR_SBUFF_IN(arg->vb_strvalue, arg->vb_length), + &(fr_sbuff_parse_rules_t){ + .escapes = &escape_rules + }, + &(tmpl_rules_t){ + .attr = { + .dict_def = request->dict, + .list_def = request_attr_request, + .allow_unknown = false, + .allow_unresolved = false, + .allow_foreign = false, + }, + .xlat = { + .runtime_el = unlang_interpret_event_list(request), + }, + .at_runtime = true, + } + ) < 0) { RPEDEBUG("Failed parsing expansion"); error: talloc_free(rctx); diff --git a/src/lib/unlang/xlat_expr.c b/src/lib/unlang/xlat_expr.c index a384ba2b97..49b3a4e2b7 100644 --- a/src/lib/unlang/xlat_expr.c +++ b/src/lib/unlang/xlat_expr.c @@ -2833,6 +2833,7 @@ static const fr_sbuff_term_t operator_terms = FR_SBUFF_TERMS( static fr_slen_t xlat_tokenize_expression_internal(TALLOC_CTX *ctx, xlat_exp_head_t **out, fr_sbuff_t *in, fr_sbuff_parse_rules_t const *p_rules, tmpl_rules_t const *t_rules, bool cond) { + int rcode; ssize_t slen; fr_sbuff_parse_rules_t *bracket_rules = NULL; fr_sbuff_parse_rules_t *terminal_rules = NULL; @@ -2907,7 +2908,12 @@ static fr_slen_t xlat_tokenize_expression_internal(TALLOC_CTX *ctx, xlat_exp_hea * Add nodes that need to be bootstrapped to * the registry. */ - if (xlat_bootstrap(head) < 0) { + if (!t_rules || !t_rules->xlat.runtime_el) { + rcode = xlat_bootstrap(head); + } else { + rcode = xlat_instantiate_ephemeral(head, t_rules->xlat.runtime_el); + } + if (rcode < 0) { talloc_free(head); return -1; } @@ -2919,8 +2925,6 @@ static fr_slen_t xlat_tokenize_expression_internal(TALLOC_CTX *ctx, xlat_exp_hea fr_slen_t xlat_tokenize_expression(TALLOC_CTX *ctx, xlat_exp_head_t **out, fr_sbuff_t *in, fr_sbuff_parse_rules_t const *p_rules, tmpl_rules_t const *t_rules) { - fr_assert(!t_rules || !t_rules->xlat.runtime_el); - return xlat_tokenize_expression_internal(ctx, out, in, p_rules, t_rules, false); } @@ -2930,105 +2934,6 @@ fr_slen_t xlat_tokenize_condition(TALLOC_CTX *ctx, xlat_exp_head_t **out, fr_sbu return xlat_tokenize_expression_internal(ctx, out, in, p_rules, t_rules, true); } - -/** Tokenize an xlat expression at runtime - * - * This function is only for testing. It should be deleted when - * expressions are integrated into the main xlat parser. - * - * @param[in] ctx to allocate dynamic buffers in. - * @param[out] out the head of the xlat list / tree structure. - * @param[in] el for registering any I/O handlers. - * @param[in] in the format string to expand. - * @param[in] p_rules from the encompassing grammar. - * @param[in] t_rules controlling how attribute references are parsed. - * @return - * - >0 on success. - * - 0 and *head == NULL - Parse failure on first char. - * - 0 and *head != NULL - Zero length expansion - * - <0 the negative offset of the parse failure. - */ -fr_slen_t xlat_tokenize_ephemeral_expression(TALLOC_CTX *ctx, xlat_exp_head_t **out, - fr_event_list_t *el, fr_sbuff_t *in, - fr_sbuff_parse_rules_t const *p_rules, tmpl_rules_t const *t_rules) -{ - ssize_t slen; - fr_sbuff_parse_rules_t *bracket_rules = NULL; - fr_sbuff_parse_rules_t *terminal_rules = NULL; - tmpl_rules_t my_rules = { }; - xlat_exp_head_t *head; - xlat_exp_t *node = NULL; - - /* - * Whatever the caller passes, ensure that we have a - * terminal rule which ends on operators, and a terminal - * rule which ends on ')'. - */ - MEM(bracket_rules = talloc_zero(ctx, fr_sbuff_parse_rules_t)); - MEM(terminal_rules = talloc_zero(ctx, fr_sbuff_parse_rules_t)); - if (p_rules) { - *bracket_rules = *p_rules; - *terminal_rules = *p_rules; - - if (p_rules->terminals) { - MEM(terminal_rules->terminals = fr_sbuff_terminals_amerge(terminal_rules, - p_rules->terminals, - &operator_terms)); - } else { - terminal_rules->terminals = &operator_terms; - } - } else { - terminal_rules->terminals = &operator_terms; - } - MEM(bracket_rules->terminals = fr_sbuff_terminals_amerge(bracket_rules, - terminal_rules->terminals, - &bracket_terms)); - MEM(head = xlat_exp_head_alloc(ctx)); - - if (t_rules) { - my_rules = *t_rules; - head->dict = t_rules->attr.dict_def; - } - - my_rules.xlat.runtime_el = el; - my_rules.at_runtime = true; - - slen = tokenize_expression(head, &node, in, terminal_rules, &my_rules, T_INVALID, bracket_rules, p_rules, false); - talloc_free(bracket_rules); - talloc_free(terminal_rules); - - if (slen < 0) { - talloc_free(head); - FR_SBUFF_ERROR_RETURN(in); - } - - if (!node) { - *out = head; - return slen; - } - - /* - * Convert raw rcodes to xlat's. - */ - if (reparse_rcode(head, &node, true) < 0) { - talloc_free(head); - return -1; - } - - xlat_exp_insert_tail(head, node); - - /* - * Create ephemeral instance data for the xlat - */ - if (xlat_instantiate_ephemeral(head, el) < 0) { - talloc_free(head); - return -1; - } - - *out = head; - return slen; -} - /** Allow callers to see if an xlat is truthy * * So the caller can cache it, and needs to check fewer things at run diff --git a/src/lib/unlang/xlat_tokenize.c b/src/lib/unlang/xlat_tokenize.c index 3eb7972445..c43023fc3e 100644 --- a/src/lib/unlang/xlat_tokenize.c +++ b/src/lib/unlang/xlat_tokenize.c @@ -995,11 +995,7 @@ int xlat_tokenize_expansion(xlat_exp_head_t *head, fr_sbuff_t *in, MEM(node = xlat_exp_alloc(head, XLAT_TMPL, NULL, 0)); MEM(node->vpt = tmpl_alloc(node, TMPL_TYPE_XLAT, T_BARE_WORD, "", 1)); - if (t_rules->xlat.runtime_el) { - ret = xlat_tokenize_ephemeral_expression(node->vpt, &child, t_rules->xlat.runtime_el, in, &attr_p_rules, t_rules); - } else { - ret = xlat_tokenize_expression(node->vpt, &child, in, &attr_p_rules, t_rules); - } + ret = xlat_tokenize_expression(node->vpt, &child, in, &attr_p_rules, t_rules); if (ret <= 0) { talloc_free(node); return ret;