]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-settings: Add settings_get_params() to support escaping variables
authorTimo Sirainen <timo.sirainen@open-xchange.com>
Thu, 7 Mar 2024 12:51:25 +0000 (14:51 +0200)
committerAki Tuomi <aki.tuomi@open-xchange.com>
Fri, 17 Jan 2025 08:39:58 +0000 (10:39 +0200)
src/lib-settings/settings.c
src/lib-settings/settings.h

index 90c689fc3cb95445966ab98a0c4f47510fbf5d1f..e3d8bfa4c96bc9455de9b151075c8046e0ad30c5 100644 (file)
@@ -7,7 +7,6 @@
 #include "str.h"
 #include "strescape.h"
 #include "event-filter-private.h"
-#include "var-expand.h"
 #include "wildcard-match.h"
 #include "mmap-util.h"
 #include "settings.h"
@@ -130,6 +129,9 @@ struct settings_apply_ctx {
        enum settings_get_flags flags;
        pool_t temp_pool;
 
+       var_expand_escape_t *escape_func;
+       void *escape_context;
+
        const char *filter_key;
        const char *filter_value;
        const char *filter_name;
@@ -1102,6 +1104,9 @@ settings_var_expand_init(struct settings_apply_ctx *ctx)
 
        ctx->var_params.tables_arr = array_front(&init_ctx.tables);
        ctx->var_params.funcs_arr = array_front(&init_ctx.funcs);
+
+       ctx->var_params.escape_func = ctx->escape_func;
+       ctx->var_params.escape_context = ctx->escape_context;
 }
 
 static int settings_override_cmp(struct settings_override *const *set1,
@@ -1675,7 +1680,7 @@ static int
 settings_get_full(struct event *event,
                  const char *filter_key, const char *filter_value,
                  const struct setting_parser_info *info,
-                 enum settings_get_flags flags,
+                 const struct settings_get_params *params,
                  const char *source_filename,
                  unsigned int source_linenum,
                  const void **set_r, const char **error_r)
@@ -1749,7 +1754,9 @@ settings_get_full(struct event *event,
                .root = root,
                .instance = instance,
                .info = info,
-               .flags = flags,
+               .flags = params->flags,
+               .escape_func = params->escape_func,
+               .escape_context = params->escape_context,
                .filter_name = filter_name,
                .filter_key = filter_key,
                .filter_value = filter_value,
@@ -1783,7 +1790,25 @@ int settings_get(struct event *event,
                 unsigned int source_linenum,
                 const void **set_r, const char **error_r)
 {
-       int ret = settings_get_full(event, NULL, NULL, info, flags,
+       const struct settings_get_params params = {
+               .flags = flags,
+       };
+       int ret = settings_get_full(event, NULL, NULL, info, &params,
+                                   source_filename, source_linenum,
+                                   set_r, error_r);
+       i_assert(ret != 0);
+       return ret < 0 ? -1 : 0;
+}
+
+#undef settings_get_params
+int settings_get_params(struct event *event,
+                       const struct setting_parser_info *info,
+                       const struct settings_get_params *params,
+                       const char *source_filename,
+                       unsigned int source_linenum,
+                       const void **set_r, const char **error_r)
+{
+       int ret = settings_get_full(event, NULL, NULL, info, params,
                                    source_filename, source_linenum,
                                    set_r, error_r);
        i_assert(ret != 0);
@@ -1802,8 +1827,11 @@ int settings_get_filter(struct event *event,
        i_assert(filter_key != NULL);
        i_assert(filter_value != NULL);
 
+       const struct settings_get_params params = {
+               .flags = flags,
+       };
        int ret = settings_get_full(event, filter_key, filter_value, info,
-                                   flags, source_filename, source_linenum,
+                                   &params, source_filename, source_linenum,
                                    set_r, error_r);
        if (ret < 0)
                return -1;
@@ -1830,8 +1858,11 @@ int settings_try_get_filter(struct event *event,
        i_assert(filter_key != NULL);
        i_assert(filter_value != NULL);
 
+       const struct settings_get_params params = {
+               .flags = flags,
+       };
        return settings_get_full(event, filter_key, filter_value, info,
-                                flags, source_filename, source_linenum,
+                                &params, source_filename, source_linenum,
                                 set_r, error_r);
 }
 
index bbf38b7478c4bd86854eb5f207b267268e4f82fb..67e939fa6192ab5b0408a593c2efea9fac13a742 100644 (file)
@@ -1,10 +1,9 @@
 #ifndef SETTINGS_H
 #define SETTINGS_H
 
+#include "var-expand.h"
 #include "settings-parser.h"
 
-struct var_expand_params;
-
 struct settings_root;
 struct settings_mmap;
 struct settings_instance;
@@ -51,6 +50,14 @@ enum settings_get_flags {
        SETTINGS_GET_NO_KEY_VALIDATION = BIT(3),
 };
 
+struct settings_get_params {
+       /* If non-NULL, all %variables are escaped with this function. */
+       var_expand_escape_t *escape_func;
+       void *escape_context;
+
+       enum settings_get_flags flags;
+};
+
 /* Set struct settings_instance to events so settings_get() can
    use it to get instance-specific settings. */
 #define SETTINGS_EVENT_INSTANCE "settings_instance"
@@ -136,6 +143,25 @@ int settings_get(struct event *event,
                __FILE__, __LINE__, (void *)set_r, error_r)
 #endif
 
+/* Like settings_get(), but support additional parameters. */
+int settings_get_params(struct event *event,
+                       const struct setting_parser_info *info,
+                       const struct settings_get_params *params,
+                       const char *source_filename,
+                       unsigned int source_linenum,
+                       const void **set_r, const char **error_r);
+#ifdef HAVE_TYPE_CHECKS
+#  define settings_get_params(event, info, params, set_r, error_r) \
+       settings_get_params(event, info, params, \
+               __FILE__, __LINE__, (void *)set_r, 1 ? (error_r) : \
+       COMPILE_ERROR_IF_TRUE( \
+               !__builtin_types_compatible_p(typeof((*set_r)->pool), pool_t)))
+#else
+#  define settings_get_params(event, info, params, set_r, error_r) \
+       settings_get_params(event, info, params, \
+               __FILE__, __LINE__, (void *)set_r, error_r)
+#endif
+
 /* Same as settings_get(), but looks up settings for a specific named list
    filter. Use e.g. { filter_key="namespace", filter_value="inbox" }.
    Returns 0 on success, -1 on error.