]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-settings: Add comments about how settings overrides are parsed
authorTimo Sirainen <timo.sirainen@open-xchange.com>
Wed, 14 Aug 2024 20:05:46 +0000 (23:05 +0300)
committerAki Tuomi <aki.tuomi@open-xchange.com>
Wed, 12 Feb 2025 10:34:13 +0000 (12:34 +0200)
src/lib-settings/settings.c

index 75a3426226bea2add9aa18615969106308259ee7..fee3935d31e65c1a5c9690fdf3c9f3b07a629107 100644 (file)
@@ -1291,13 +1291,16 @@ settings_key_part_find(struct settings_apply_ctx *ctx, const char **key,
 {
        if (last_filter_value != NULL) {
                i_assert(last_filter_key != NULL);
+               const char *key_prefix = last_filter_key;
+               /* last_filter_key was already converted to "mailbox_subname".
+                  But for setting name auto-prefixing it needs to be "mailbox"
+                  again. */
+               if (strcmp(key_prefix, SETTINGS_EVENT_MAILBOX_NAME_WITHOUT_PREFIX) == 0)
+                       key_prefix = SETTINGS_EVENT_MAILBOX_NAME_WITH_PREFIX;
                /* Try filter/name/key -> filter_name_key, and fallback to
                   filter_key. Do this before the non-prefixed check, so e.g.
                   inet_listener/imap/ssl won't try to change the global ssl
                   setting. */
-               const char *key_prefix = last_filter_key;
-               if (strcmp(key_prefix, SETTINGS_EVENT_MAILBOX_NAME_WITHOUT_PREFIX) == 0)
-                       key_prefix = SETTINGS_EVENT_MAILBOX_NAME_WITH_PREFIX;
                const char *prefixed_key =
                        t_strdup_printf("%s_%s_%s", key_prefix,
                                        last_filter_value, *key);
@@ -1322,6 +1325,25 @@ settings_override_filter_match(struct settings_apply_ctx *ctx,
                               struct settings_override *set,
                               const char **error_r)
 {
+       /* Handling filters for overrides works in an incremental way, filling
+          set->filter more and more as it knows what the setting key's parts
+          mean. For example an override:
+
+          namespace/inbox/mailbox/foo/special_use=\Drafts
+
+          For this to actually work, this function must become called with
+          ctx->info == &mail_storage_setting_parser_info to translate the
+          "namespace/inbox/" prefix into set->filter. Next this must be called
+          with ctx->info == &mail_namespace_setting_parser_info to further add
+          "mailbox/foo/" into set->filter. Finally when this function is
+          called to lookup ctx->info == &mailbox_setting_parser_info, it only
+          needs to know about the "special_use" key.
+
+          Unfortunately this means that there must be settings lookups in
+          the correct order to do the filter prefix to set->filter conversion.
+          This is expected to work for most common filters, but it could cause
+          problems in some cases. Debugging what is going wrong for overrides
+          is rather painful. */
        const struct failure_context failure_ctx = {
                .type = LOG_TYPE_DEBUG
        };