summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEdward Thomson <ethomson@edwardthomson.com>2018-09-06 19:19:58 +0100
committerGitHub <noreply@github.com>2018-09-06 19:19:58 +0100
commit0bcb1d5fabfa9e3170b1de0bd6603758ce2a39d0 (patch)
treef4f907c0ff081b39b31052fff5482906a9a06cf4
parent695067f7d65ff6de2162917ce3092a2307020e59 (diff)
parentf26946358f0ddf106f54e4a9d7eaaf7b60a2c20f (diff)
downloadlibgit2-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.c29
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;