summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEdward Thomson <ethomson@edwardthomson.com>2023-03-27 11:58:42 +0100
committerGitHub <noreply@github.com>2023-03-27 11:58:42 +0100
commit2f20fe8869d7a1df7c9b7a9e2939c1a20533c6dc (patch)
tree30ce5a7c31f5463e8d143d4f90468e35b82d1f7f
parent9bfad74dc029f163f296d09df56a42b97a38f4c1 (diff)
parente25f9a9bb85e062aeff3d0713e35dd1ad31962d3 (diff)
downloadlibgit2-2f20fe8869d7a1df7c9b7a9e2939c1a20533c6dc.tar.gz
Merge pull request #6505 from libgit2/ethomson/extension_madness
repo: don't allow repeated extensions
-rw-r--r--src/libgit2/repository.c38
-rw-r--r--tests/libgit2/core/opts.c29
2 files changed, 56 insertions, 11 deletions
diff --git a/src/libgit2/repository.c b/src/libgit2/repository.c
index 8c41167a1..e16413f76 100644
--- a/src/libgit2/repository.c
+++ b/src/libgit2/repository.c
@@ -1632,7 +1632,7 @@ static const char *builtin_extensions[] = {
"objectformat"
};
-static git_vector user_extensions = GIT_VECTOR_INIT;
+static git_vector user_extensions = { 0, git__strcmp_cb };
static int check_valid_extension(const git_config_entry *entry, void *payload)
{
@@ -1773,7 +1773,7 @@ int git_repository__extensions(char ***out, size_t *out_len)
char *extension;
size_t i, j;
- if (git_vector_init(&extensions, 8, NULL) < 0)
+ if (git_vector_init(&extensions, 8, git__strcmp_cb) < 0)
return -1;
for (i = 0; i < ARRAY_SIZE(builtin_extensions); i++) {
@@ -1805,21 +1805,49 @@ int git_repository__extensions(char ***out, size_t *out_len)
return -1;
}
+ git_vector_sort(&extensions);
+
*out = (char **)git_vector_detach(out_len, NULL, &extensions);
return 0;
}
+static int dup_ext_err(void **old, void *extension)
+{
+ GIT_UNUSED(old);
+ GIT_UNUSED(extension);
+ return GIT_EEXISTS;
+}
+
int git_repository__set_extensions(const char **extensions, size_t len)
{
char *extension;
- size_t i;
+ size_t i, j;
+ int error;
git_repository__free_extensions();
for (i = 0; i < len; i++) {
- if ((extension = git__strdup(extensions[i])) == NULL ||
- git_vector_insert(&user_extensions, extension) < 0)
+ bool is_builtin = false;
+
+ for (j = 0; j < ARRAY_SIZE(builtin_extensions); j++) {
+ if (strcmp(builtin_extensions[j], extensions[i]) == 0) {
+ is_builtin = true;
+ break;
+ }
+ }
+
+ if (is_builtin)
+ continue;
+
+ if ((extension = git__strdup(extensions[i])) == NULL)
return -1;
+
+ if ((error = git_vector_insert_sorted(&user_extensions, extension, dup_ext_err)) < 0) {
+ git__free(extension);
+
+ if (error != GIT_EEXISTS)
+ return -1;
+ }
}
return 0;
diff --git a/tests/libgit2/core/opts.c b/tests/libgit2/core/opts.c
index 486ff58c6..1aa095adf 100644
--- a/tests/libgit2/core/opts.c
+++ b/tests/libgit2/core/opts.c
@@ -50,9 +50,9 @@ void test_core_opts__extensions_add(void)
cl_git_pass(git_libgit2_opts(GIT_OPT_GET_EXTENSIONS, &out));
cl_assert_equal_sz(out.count, 3);
- cl_assert_equal_s("noop", out.strings[0]);
- cl_assert_equal_s("objectformat", out.strings[1]);
- cl_assert_equal_s("foo", out.strings[2]);
+ cl_assert_equal_s("foo", out.strings[0]);
+ cl_assert_equal_s("noop", out.strings[1]);
+ cl_assert_equal_s("objectformat", out.strings[2]);
git_strarray_dispose(&out);
}
@@ -66,9 +66,26 @@ void test_core_opts__extensions_remove(void)
cl_git_pass(git_libgit2_opts(GIT_OPT_GET_EXTENSIONS, &out));
cl_assert_equal_sz(out.count, 3);
- cl_assert_equal_s("objectformat", out.strings[0]);
- cl_assert_equal_s("bar", out.strings[1]);
- cl_assert_equal_s("baz", out.strings[2]);
+ cl_assert_equal_s("bar", out.strings[0]);
+ cl_assert_equal_s("baz", out.strings[1]);
+ cl_assert_equal_s("objectformat", out.strings[2]);
+
+ git_strarray_dispose(&out);
+}
+
+void test_core_opts__extensions_uniq(void)
+{
+ const char *in[] = { "foo", "noop", "bar", "bar", "foo", "objectformat" };
+ git_strarray out = { 0 };
+
+ cl_git_pass(git_libgit2_opts(GIT_OPT_SET_EXTENSIONS, in, ARRAY_SIZE(in)));
+ cl_git_pass(git_libgit2_opts(GIT_OPT_GET_EXTENSIONS, &out));
+
+ cl_assert_equal_sz(out.count, 4);
+ cl_assert_equal_s("bar", out.strings[0]);
+ cl_assert_equal_s("foo", out.strings[1]);
+ cl_assert_equal_s("noop", out.strings[2]);
+ cl_assert_equal_s("objectformat", out.strings[3]);
git_strarray_dispose(&out);
}