From: Arran Cudbard-Bell Date: Wed, 1 Dec 2021 14:38:23 +0000 (-0600) Subject: Record the input type %{ vs %( and expose the validation functions X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2deb7039ddae0761a5ef67ef0f224bf162a6f49b;p=thirdparty%2Ffreeradius-server.git Record the input type %{ vs %( and expose the validation functions Also do more validation when we're resolving a previously unresolved xlat --- diff --git a/src/lib/unlang/xlat.h b/src/lib/unlang/xlat.h index 810319e9db2..c1a8ea9be5d 100644 --- a/src/lib/unlang/xlat.h +++ b/src/lib/unlang/xlat.h @@ -361,6 +361,10 @@ static inline size_t xlat_aprint(TALLOC_CTX *ctx, char **out, xlat_exp_t const * SBUFF_OUT_TALLOC_FUNC_NO_LEN_DEF(xlat_print, node, e_rules); } +int xlat_validate_function_mono(xlat_exp_t *node); + +int xlat_validate_function_args(xlat_exp_t *node); + void xlat_debug(xlat_exp_t const *node); bool xlat_is_value_box(xlat_exp_t const *head); diff --git a/src/lib/unlang/xlat_priv.h b/src/lib/unlang/xlat_priv.h index b0447cb72a5..8927ca27fe0 100644 --- a/src/lib/unlang/xlat_priv.h +++ b/src/lib/unlang/xlat_priv.h @@ -104,6 +104,9 @@ typedef struct { xlat_inst_t *inst; //!< Instance data for the #xlat_t. xlat_thread_inst_t *thread_inst; //!< Thread specific instance. ///< ONLY USED FOR EPHEMERAL XLATS. + + xlat_input_type_t input_type; //!< The input type used inferred from the + ///< bracketing style. } xlat_call_t; /** An xlat expansion node diff --git a/src/lib/unlang/xlat_tokenize.c b/src/lib/unlang/xlat_tokenize.c index 85c2f030c00..e586d8aa8d7 100644 --- a/src/lib/unlang/xlat_tokenize.c +++ b/src/lib/unlang/xlat_tokenize.c @@ -369,7 +369,7 @@ static inline int xlat_tokenize_regex(TALLOC_CTX *ctx, xlat_exp_t **head, xlat_f } #endif -static inline int xlat_validate_function_mono(xlat_exp_t *node) +int xlat_validate_function_mono(xlat_exp_t *node) { fr_assert(node->type == XLAT_FUNC); @@ -450,6 +450,15 @@ static inline int xlat_tokenize_function_mono(TALLOC_CTX *ctx, xlat_exp_t **head node->flags = func->flags; } + /* + * Record the calling style, this is useful + * for checking later with unresolved + * functions, for printing accurate debug + * info, and for weird xlats like the + * redundant xlat + */ + node->call.input_type = XLAT_INPUT_MONO; + fr_sbuff_next(in); /* Skip the ':' */ XLAT_DEBUG("FUNC-ARGS <-- %s ... %pV", node->fmt, fr_box_strvalue_len(fr_sbuff_current(in), fr_sbuff_remaining(in))); @@ -480,7 +489,7 @@ static inline int xlat_tokenize_function_mono(TALLOC_CTX *ctx, xlat_exp_t **head return 0; } -static inline int xlat_validate_function_args(xlat_exp_t *node) +int xlat_validate_function_args(xlat_exp_t *node) { xlat_arg_parser_t const *arg_p; xlat_exp_t *child = node->child; @@ -568,7 +577,7 @@ static inline int xlat_tokenize_function_args(TALLOC_CTX *ctx, xlat_exp_t **head node->flags.needs_resolving = true; /* Needs resolution during pass2 */ } else { if (func && (func->input_type != XLAT_INPUT_ARGS)) { - fr_strerror_const("Function should be called using the syntax %{func:arg}"); + fr_strerror_const("Function should be called using %{func:arg} syntax"); error: talloc_free(node); return -1; @@ -577,6 +586,15 @@ static inline int xlat_tokenize_function_args(TALLOC_CTX *ctx, xlat_exp_t **head node->flags = func->flags; } + /* + * Record the calling style, this is useful + * for checking later with unresolved + * functions, for printing accurate debug + * info, and for weird xlats like the + * redundant xlat + */ + node->call.input_type = XLAT_INPUT_ARGS; + fr_sbuff_next(in); /* Skip the ':' */ XLAT_DEBUG("FUNC-ARGS <-- %s ... %pV", node->fmt, fr_box_strvalue_len(fr_sbuff_current(in), fr_sbuff_remaining(in))); @@ -1732,10 +1750,20 @@ int xlat_resolve(xlat_exp_t **head, xlat_flags_t *flags, xlat_res_rules_t const break; case XLAT_INPUT_MONO: + if (node->call.input_type != XLAT_INPUT_MONO) { + fr_strerror_const("Function should be called using %{func:arg} syntax"); + return -1; + + } if (xlat_validate_function_mono(node) < 0) return -1; break; case XLAT_INPUT_ARGS: + if (node->call.input_type != XLAT_INPUT_ARGS) { + fr_strerror_const("Function takes defined arguments and should " + "be called using %(func:args) syntax"); + return -1; + } if (xlat_validate_function_args(node) < 0) return -1; break; }