summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRussell Belfer <rb@github.com>2013-04-30 03:15:45 -0700
committerRussell Belfer <rb@github.com>2013-04-30 03:15:45 -0700
commit0a1755c045b930de474883eb6e7fedcc3403b494 (patch)
treecf129ba2df0a75873edc84579f72ea29044747de
parent4157851076d476b3b7f9a8bb9b85497517b14cdf (diff)
downloadlibgit2-0a1755c045b930de474883eb6e7fedcc3403b494.tar.gz
Catch issue in config set with no config file
This prevents a segfault when setting a value in the config of a repository that doesn't have a config file.
-rw-r--r--src/config.c6
-rw-r--r--tests-clar/repo/open.c35
2 files changed, 41 insertions, 0 deletions
diff --git a/src/config.c b/src/config.c
index 3c0bbe9a7..2e1268ef3 100644
--- a/src/config.c
+++ b/src/config.c
@@ -373,6 +373,12 @@ int git_config_set_string(git_config *cfg, const char *name, const char *value)
}
internal = git_vector_get(&cfg->files, 0);
+ if (!internal) {
+ /* Should we auto-vivify .git/config? Tricky from this location */
+ giterr_set(GITERR_CONFIG, "Cannot set value when no config files exist");
+ return GIT_ENOTFOUND;
+ }
+
file = internal->file;
error = file->set(file, name, value);
diff --git a/tests-clar/repo/open.c b/tests-clar/repo/open.c
index 7f93ae91a..6b5253797 100644
--- a/tests-clar/repo/open.c
+++ b/tests-clar/repo/open.c
@@ -280,3 +280,38 @@ void test_repo_open__opening_a_non_existing_repository_returns_ENOTFOUND(void)
git_repository *repo;
cl_assert_equal_i(GIT_ENOTFOUND, git_repository_open(&repo, "i-do-not/exist"));
}
+
+void test_repo_open__no_config(void)
+{
+ git_buf path = GIT_BUF_INIT;
+ git_repository *repo;
+ git_config *config;
+
+ cl_fixture_sandbox("empty_standard_repo");
+ cl_git_pass(cl_rename("empty_standard_repo/.gitted", "empty_standard_repo/.git"));
+
+ /* remove local config */
+ cl_git_pass(git_futils_rmdir_r(
+ "empty_standard_repo/.git/config", NULL, GIT_RMDIR_REMOVE_FILES));
+
+ /* isolate from system level configs */
+ cl_must_pass(p_mkdir("alternate", 0777));
+ cl_git_pass(git_path_prettify(&path, "alternate", NULL));
+ cl_git_pass(git_libgit2_opts(
+ GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, path.ptr));
+ cl_git_pass(git_libgit2_opts(
+ GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_SYSTEM, path.ptr));
+ cl_git_pass(git_libgit2_opts(
+ GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_XDG, path.ptr));
+
+ git_buf_free(&path);
+
+ cl_git_pass(git_repository_open(&repo, "empty_standard_repo"));
+ cl_git_pass(git_repository_config(&config, repo));
+
+ cl_git_fail(git_config_set_string(config, "test.set", "42"));
+
+ git_config_free(config);
+ git_repository_free(repo);
+ cl_fixture_cleanup("empty_standard_repo");
+}