]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
Record the input type %{ vs %( and expose the validation functions
authorArran Cudbard-Bell <a.cudbardb@freeradius.org>
Wed, 1 Dec 2021 14:38:23 +0000 (08:38 -0600)
committerArran Cudbard-Bell <a.cudbardb@freeradius.org>
Wed, 1 Dec 2021 20:06:47 +0000 (14:06 -0600)
Also do more validation when we're resolving a previously unresolved xlat

src/lib/unlang/xlat.h
src/lib/unlang/xlat_priv.h
src/lib/unlang/xlat_tokenize.c

index 810319e9db2e32aac34b790d8b0d819497f06d50..c1a8ea9be5d6edc820aef3d2b97d93bd4ee534fb 100644 (file)
@@ -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);
index b0447cb72a53fce98af933c1bc4adbc65e173055..8927ca27fe0766d5f9334c2cb99d311c8e177edf 100644 (file)
@@ -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
index 85c2f030c0001f63f2e8e8e348f5c7cd3afebe45..e586d8aa8d729d27df2aef63ca8ca4a10ad44817 100644 (file)
@@ -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;
                        }