diff options
author | Edward Thomson <ethomson@edwardthomson.com> | 2018-09-06 19:19:58 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-09-06 19:19:58 +0100 |
commit | 0bcb1d5fabfa9e3170b1de0bd6603758ce2a39d0 (patch) | |
tree | f4f907c0ff081b39b31052fff5482906a9a06cf4 | |
parent | 695067f7d65ff6de2162917ce3092a2307020e59 (diff) | |
parent | f26946358f0ddf106f54e4a9d7eaaf7b60a2c20f (diff) | |
download | libgit2-0bcb1d5fabfa9e3170b1de0bd6603758ce2a39d0.tar.gz |
Merge pull request #4799 from pks-t/pks/config-multivar-quadratic
config_file: fix quadratic behaviour when adding config multivars
-rw-r--r-- | src/config_file.c | 29 |
1 files changed, 17 insertions, 12 deletions
diff --git a/src/config_file.c b/src/config_file.c index 050bcfc92..26bc200df 100644 --- a/src/config_file.c +++ b/src/config_file.c @@ -25,6 +25,7 @@ typedef struct config_entry_list { struct config_entry_list *next; + struct config_entry_list *last; git_config_entry *entry; } config_entry_list; @@ -131,15 +132,11 @@ int git_config_file_normalize_section(char *start, char *end) static void config_entry_list_append(config_entry_list **list, config_entry_list *entry) { - config_entry_list *head = *list; - - if (head) { - while (head->next != NULL) - head = head->next; - head->next = entry; - } else { + if (*list) + (*list)->last->next = entry; + else *list = entry; - } + (*list)->last = entry; } /* Add or append the new config option */ @@ -155,6 +152,17 @@ static int diskfile_entries_append(diskfile_entries *entries, git_config_entry * pos = git_strmap_lookup_index(entries->map, entry->name); if (!git_strmap_valid_index(entries->map, pos)) { + /* + * We only ever inspect `last` from the first config + * entry in a multivar. In case where this new entry is + * the first one in the entry map, it will also be the + * last one at the time of adding it, which is + * why we set `last` here to itself. Otherwise we + * do not have to set `last` and leave it set to + * `NULL`. + */ + var->last = var; + git_strmap_insert(entries->map, entry->name, var, &error); if (error > 0) @@ -517,10 +525,7 @@ static int config_get(git_config_backend *cfg, const char *key, git_config_entry } var = git_strmap_value_at(entry_map, pos); - while (var->next) - var = var->next; - - *out = var->entry; + *out = var->last->entry; (*out)->free = free_diskfile_entry; (*out)->payload = entries; |