diff options
| author | Patrick Steinhardt <ps@pks.im> | 2019-07-21 15:10:34 +0200 |
|---|---|---|
| committer | Patrick Steinhardt <ps@pks.im> | 2019-07-21 15:16:34 +0200 |
| commit | 2766b92de755871b666217912d865c46ed289011 (patch) | |
| tree | 1f81ac39c55a4bf0d4bb616f59c49184b8930948 | |
| parent | 9fac8b78347b5830bc1068efd804fa25ebc9ec1e (diff) | |
| download | libgit2-2766b92de755871b666217912d865c46ed289011.tar.gz | |
config_file: refresh when creating an iterator
When creating a new iterator for a config file backend, then we should
always make sure that we're up to date by calling `config_refresh`.
Otherwise, we might not notice when another process has modified the
configuration file and thus will represent outdated values.
Add two tests to config::stress that verify that we get up-to-date
values when reading configuration entries via `git_config_iterator`.
| -rw-r--r-- | src/config_file.c | 9 | ||||
| -rw-r--r-- | tests/config/stress.c | 45 |
2 files changed, 49 insertions, 5 deletions
diff --git a/src/config_file.c b/src/config_file.c index 1b674b135..88bba90a7 100644 --- a/src/config_file.c +++ b/src/config_file.c @@ -270,13 +270,12 @@ static int config_iterator_new( struct git_config_backend *backend) { diskfile_header *bh = GIT_CONTAINER_OF(backend, diskfile_header, parent); - git_config_entries *entries; + git_config_entries *entries = NULL; int error; - if ((error = git_config_entries_dup(&entries, bh->entries)) < 0) - return error; - - if ((error = git_config_entries_iterator_new(iter, entries)) < 0) + if ((error = config_refresh(backend)) < 0 || + (error = git_config_entries_dup(&entries, bh->entries)) < 0 || + (error = git_config_entries_iterator_new(iter, entries)) < 0) goto out; out: diff --git a/tests/config/stress.c b/tests/config/stress.c index 4fb0f3b26..4ee234f17 100644 --- a/tests/config/stress.c +++ b/tests/config/stress.c @@ -131,3 +131,48 @@ void test_config_stress__quick_write(void) git_config_free(config_r); git_config_free(config_w); } + +static int foreach_cb(const git_config_entry *entry, void *payload) +{ + if (!strcmp(entry->name, "key.value")) { + *(char **)payload = git__strdup(entry->value); + return 0; + } + return -1; +} + +void test_config_stress__foreach_refreshes(void) +{ + git_config *config_w, *config_r; + char *value = NULL; + + cl_git_pass(git_config_open_ondisk(&config_w, "./cfg")); + cl_git_pass(git_config_open_ondisk(&config_r, "./cfg")); + + cl_git_pass(git_config_set_string(config_w, "key.value", "1")); + cl_git_pass(git_config_foreach_match(config_r, "key.value", foreach_cb, &value)); + + cl_assert_equal_s(value, "1"); + + git_config_free(config_r); + git_config_free(config_w); + git__free(value); +} + +void test_config_stress__foreach_refreshes_snapshot(void) +{ + git_config *config, *snapshot; + char *value = NULL; + + cl_git_pass(git_config_open_ondisk(&config, "./cfg")); + + cl_git_pass(git_config_set_string(config, "key.value", "1")); + cl_git_pass(git_config_snapshot(&snapshot, config)); + cl_git_pass(git_config_foreach_match(snapshot, "key.value", foreach_cb, &value)); + + cl_assert_equal_s(value, "1"); + + git_config_free(snapshot); + git_config_free(config); + git__free(value); +} |
