From 5f85714e1f80a16f95c646fbb2124d8f963c0a2c Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Mon, 4 Mar 2024 14:55:40 +0000 Subject: [PATCH] config: don't git_config_free an aborted transaction When a configuration transaction is freed with `git_transaction_free` - without first committing it - we should not `git_config_free`. We never increased the refcount, so we certainly shouldn't decrease it. Also, add a test around aborting a transaction without committing it. --- tests/libgit2/config/write.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/tests/libgit2/config/write.c b/tests/libgit2/config/write.c index 9d8c3fe94..c71d4f6dc 100644 --- a/tests/libgit2/config/write.c +++ b/tests/libgit2/config/write.c @@ -696,6 +696,36 @@ void test_config_write__locking(void) git_config_free(cfg); } +void test_config_write__abort_lock(void) +{ + git_config *cfg; + git_config_entry *entry; + git_transaction *tx; + const char *filename = "locked-file"; + + /* Open the config and lock it */ + cl_git_mkfile(filename, "[section]\n\tname = value\n"); + cl_git_pass(git_config_open_ondisk(&cfg, filename)); + cl_git_pass(git_config_get_entry(&entry, cfg, "section.name")); + cl_assert_equal_s("value", entry->value); + git_config_entry_free(entry); + cl_git_pass(git_config_lock(&tx, cfg)); + + /* Change entries in the locked backend */ + cl_git_pass(git_config_set_string(cfg, "section.name", "other value")); + cl_git_pass(git_config_set_string(cfg, "section2.name3", "more value")); + + git_transaction_free(tx); + + /* Now that we've unlocked it, we should see no changes */ + cl_git_pass(git_config_get_entry(&entry, cfg, "section.name")); + cl_assert_equal_s("value", entry->value); + git_config_entry_free(entry); + cl_git_fail_with(GIT_ENOTFOUND, git_config_get_entry(&entry, cfg, "section2.name3")); + + git_config_free(cfg); +} + void test_config_write__repeated(void) { const char *filename = "config-repeated";