From 5a70df94364f5ca7cbf6db2a881b291b8476c4bf Mon Sep 17 00:00:00 2001 From: Ryan Roden-Corrent Date: Tue, 21 Apr 2015 15:57:20 -0400 Subject: [PATCH] Test setting config var under duplicate header. Add a test that exposes a bug in config_write. It is valid to have multiple separate headers for the same config section, but config_write will exit after finding the first matching section in certain situations. This test proves that config_write will duplicate a variable that already exists instead of overwriting it if the variable is defined under a duplicate section header. --- tests/config/write.c | 49 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/tests/config/write.c b/tests/config/write.c index 60d900535..a6c20e21f 100644 --- a/tests/config/write.c +++ b/tests/config/write.c @@ -145,6 +145,55 @@ void test_config_write__delete_value_with_duplicate_header(void) git_config_free(cfg); } +/* + * This test exposes a bug where duplicate section headers could cause + * config_write to add a new entry when one already exists. + */ +void test_config_write__add_value_with_duplicate_header(void) +{ + const char *file_name = "config-duplicate-insert"; + const char *entry_name = "foo.c"; + const char *old_val = "old"; + const char *new_val = "new"; + const char *str; + git_config *cfg, *snapshot; + + /* c = old should be replaced by c = new. + * The bug causes c = new to be inserted under the first 'foo' header. + */ + const char *file_content = + "[foo]\n" \ + " a = b\n" \ + "[other]\n" \ + " a = b\n" \ + "[foo]\n" \ + " c = old\n"; + + /* Write the test config */ + cl_git_mkfile(file_name, file_content); + cl_git_pass(git_config_open_ondisk(&cfg, file_name)); + + /* make sure the expected entry (foo.c) exists */ + cl_git_pass(git_config_snapshot(&snapshot, cfg)); + cl_git_pass(git_config_get_string(&str, snapshot, entry_name)); + cl_assert_equal_s(old_val, str); + git_config_free(snapshot); + + /* Try setting foo.c to something else */ + cl_git_pass(git_config_set_string(cfg, entry_name, new_val)); + git_config_free(cfg); + + /* Reopen the file and make sure the new value was set */ + cl_git_pass(git_config_open_ondisk(&cfg, file_name)); + cl_git_pass(git_config_snapshot(&snapshot, cfg)); + cl_git_pass(git_config_get_string(&str, snapshot, entry_name)); + cl_assert_equal_s(new_val, str); + + /* Cleanup */ + git_config_free(snapshot); + git_config_free(cfg); +} + void test_config_write__overwrite_value_with_duplicate_header(void) { const char *file_name = "config-duplicate-header";