From: Arran Cudbard-Bell Date: Mon, 15 Mar 2021 22:04:57 +0000 (+0000) Subject: Additional sanity checking X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=3bd8d9bd4fe8baaf10e1be54cf40aac83f6bbd45;p=thirdparty%2Ffreeradius-server.git Additional sanity checking --- diff --git a/src/lib/unlang/xlat.h b/src/lib/unlang/xlat.h index 9f3264ea4c0..1d63e5a5662 100644 --- a/src/lib/unlang/xlat.h +++ b/src/lib/unlang/xlat.h @@ -120,7 +120,7 @@ typedef struct { ///< tainted ones. fr_type_t type; //!< Type to cast argument to. xlat_escape_func_t func; //!< Function to handle tainted values. - void *uctx; //!< Arcument to escape callback. + void *uctx; //!< Argument to pass to escape callback. } xlat_arg_parser_t; #define XLAT_ARG_PARSER_TERMINATOR { .required = false, .concat = false, .single = false, .variadic = false, \ @@ -367,9 +367,9 @@ xlat_t *xlat_register_legacy(void *mod_inst, char const *name, xlat_t *xlat_register(TALLOC_CTX *ctx, char const *name, xlat_func_t func, bool needs_async) CC_HINT(nonnull(2)); -void xlat_func_args(xlat_t *xlat, xlat_arg_parser_t const args[]) CC_HINT(nonnull); +int xlat_func_args(xlat_t *xlat, xlat_arg_parser_t const args[]) CC_HINT(nonnull); -void xlat_func_mono(xlat_t *xlat, xlat_arg_parser_t const *arg) CC_HINT(nonnull); +int xlat_func_mono(xlat_t *xlat, xlat_arg_parser_t const *arg) CC_HINT(nonnull); void xlat_internal(xlat_t *xlat); diff --git a/src/lib/unlang/xlat_builtin.c b/src/lib/unlang/xlat_builtin.c index 2809fe269c8..31f33d218e8 100644 --- a/src/lib/unlang/xlat_builtin.c +++ b/src/lib/unlang/xlat_builtin.c @@ -377,11 +377,41 @@ xlat_t *xlat_register(TALLOC_CTX *ctx, char const *name, xlat_func_t func, bool * * @param[in] arg specification to validate. */ -static inline void xlat_arg_parser_validate(xlat_arg_parser_t const *arg) +static inline int xlat_arg_parser_validate(xlat_arg_parser_t const *arg, bool last) { if (arg->concat) { - fr_assert((arg->type == FR_TYPE_STRING) || (arg->type == FR_TYPE_OCTETS)); + if (!fr_cond_assert_msg((arg->type == FR_TYPE_STRING) || (arg->type == FR_TYPE_OCTETS), + "concat type must be string or octets")) return -1; + + if (!fr_cond_assert_msg(!arg->single, "concat and single are mutually exclusive")) return -1; + } + + if (arg->single) { + if (!fr_cond_assert_msg(!arg->concat, "single and concat are mutually exclusive")) return -1; + } + + if (arg->variadic) { + if (!fr_cond_assert_msg(last, "variadic can only be set on the last argument")) return -1; + } + + if (arg->always_escape) { + if (!fr_cond_assert_msg(arg->func, "always_escape requires an escape func")) return -1; + } + + if (arg->uctx) { + if (!fr_cond_assert_msg(arg->func, "uctx requires an escape func")) return -1; + } + + switch (arg->type) { + case FR_TYPE_VALUE: + break; + + default: + fr_assert_fail("type must be a leaf box type"); + return -1; } + + return 0; } /** Register the arguments of an xlat @@ -390,15 +420,21 @@ static inline void xlat_arg_parser_validate(xlat_arg_parser_t const *arg) * * @param[in,out] x to have it's arguments registered * @param[in] args to be registered + * @return + * - 0 on success. + * - < 0 on failure. */ -void xlat_func_args(xlat_t *x, xlat_arg_parser_t const args[]) +int xlat_func_args(xlat_t *x, xlat_arg_parser_t const args[]) { xlat_arg_parser_t const *arg = args; - for (arg = args; arg->type != FR_TYPE_NULL; arg++) xlat_arg_parser_validate(arg); - + for (arg = args; arg->type != FR_TYPE_NULL; arg++) { + if (xlat_arg_parser_validate(arg, (arg + 1)->type == FR_TYPE_NULL) < 0) return -1; + } x->args = args; x->input_type = XLAT_INPUT_ARGS; + + return 0; } /** Register the argument of an xlat @@ -407,12 +443,18 @@ void xlat_func_args(xlat_t *x, xlat_arg_parser_t const args[]) * * @param[in,out] x to have it's arguments registered * @param[in] arg to be registered + * @return + * - 0 on success. + * - < 0 on failure. */ -void xlat_func_mono(xlat_t *x, xlat_arg_parser_t const *arg) +int xlat_func_mono(xlat_t *x, xlat_arg_parser_t const *arg) { - xlat_arg_parser_validate(arg); + if (xlat_arg_parser_validate(arg, true) < 0) return -1; + x->args = arg; x->input_type = XLAT_INPUT_MONO; + + return 0; } /** Mark an xlat function as internal