]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-settings: Fixed parsing settings when the key was duplicated to multiple roots.
authorTimo Sirainen <tss@iki.fi>
Mon, 15 Nov 2010 16:42:19 +0000 (16:42 +0000)
committerTimo Sirainen <tss@iki.fi>
Mon, 15 Nov 2010 16:42:19 +0000 (16:42 +0000)
Previously only the first one got the value set, now all of them get it.

src/lib-settings/settings-parser.c

index bfdd57986df7f7cbd64b22679370a569257e6844..ea03f5edb7deb2926a0f0144d5ec80a766c2ac5c 100644 (file)
@@ -651,9 +651,9 @@ settings_parse(struct setting_parser_context *ctx, struct setting_link *link,
 }
 
 static bool
-settings_find_key(struct setting_parser_context *ctx, const char *key,
-                 const struct setting_define **def_r,
-                 struct setting_link **link_r)
+settings_find_key_nth(struct setting_parser_context *ctx, const char *key,
+                     unsigned int n, const struct setting_define **def_r,
+                     struct setting_link **link_r)
 {
        const struct setting_define *def;
        struct setting_link *link;
@@ -663,12 +663,14 @@ settings_find_key(struct setting_parser_context *ctx, const char *key,
        /* try to find from roots */
        for (i = 0; i < ctx->root_count; i++) {
                def = setting_define_find(ctx->roots[i].info, key);
-               if (def != NULL) {
+               if (def != NULL && n-- == 0) {
                        *def_r = def;
                        *link_r = &ctx->roots[i];
                        return TRUE;
                }
        }
+       if (n > 0)
+               return FALSE;
 
        /* try to find from links */
        end = strrchr(key, SETTINGS_SEPARATOR);
@@ -689,6 +691,14 @@ settings_find_key(struct setting_parser_context *ctx, const char *key,
        }
 }
 
+static bool
+settings_find_key(struct setting_parser_context *ctx, const char *key,
+                 const struct setting_define **def_r,
+                 struct setting_link **link_r)
+{
+       return settings_find_key_nth(ctx, key, 0, def_r, link_r);
+}
+
 static void
 settings_parse_strlist(struct setting_parser_context *ctx,
                       struct setting_link *link,
@@ -720,8 +730,15 @@ static int settings_parse_keyvalue(struct setting_parser_context *ctx,
 {
        const struct setting_define *def;
        struct setting_link *link;
+       unsigned int n = 0;
+
+       if (!settings_find_key(ctx, key, &def, &link)) {
+               ctx->error = p_strconcat(ctx->parser_pool,
+                                        "Unknown setting: ", key, NULL);
+               return 0;
+       }
 
-       if (settings_find_key(ctx, key, &def, &link)) {
+       do {
                if (link->info == &strlist_info) {
                        settings_parse_strlist(ctx, link, key, value);
                        return 1;
@@ -729,12 +746,9 @@ static int settings_parse_keyvalue(struct setting_parser_context *ctx,
 
                if (settings_parse(ctx, link, def, key, value) < 0)
                        return -1;
-               return 1;
-       } else {
-               ctx->error = p_strconcat(ctx->parser_pool,
-                                        "Unknown setting: ", key, NULL);
-               return 0;
-       }
+               /* there may be more instances of the setting */
+       } while (settings_find_key_nth(ctx, key, ++n, &def, &link));
+       return 1;
 }
 
 bool settings_parse_is_valid_key(struct setting_parser_context *ctx,