Merge pull request #4837 from pks-t/cmn/reject-option-submodule-url-path submodule: ignore path and url attributes if they look like options
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145
diff --git a/src/submodule.c b/src/submodule.c
index 9231f08..825e85a 100644
--- a/src/submodule.c
+++ b/src/submodule.c
@@ -1865,6 +1865,14 @@ static int get_value(const char **out, git_config *cfg, git_buf *buf, const char
return error;
}
+static bool looks_like_command_line_option(const char *s)
+{
+ if (s && s[0] == '-')
+ return true;
+
+ return false;
+}
+
static int submodule_read_config(git_submodule *sm, git_config *cfg)
{
git_buf key = GIT_BUF_INIT;
@@ -1878,24 +1886,31 @@ static int submodule_read_config(git_submodule *sm, git_config *cfg)
if ((error = get_value(&value, cfg, &key, sm->name, "path")) == 0) {
in_config = 1;
+ /* We would warn here if we had that API */
+ if (!looks_like_command_line_option(value)) {
/*
* TODO: if case insensitive filesystem, then the following strcmp
* should be strcasecmp
*/
- if (strcmp(sm->name, value) != 0) {
- if (sm->path != sm->name)
- git__free(sm->path);
- sm->path = git__strdup(value);
- GITERR_CHECK_ALLOC(sm->path);
+ if (strcmp(sm->name, value) != 0) {
+ if (sm->path != sm->name)
+ git__free(sm->path);
+ sm->path = git__strdup(value);
+ GITERR_CHECK_ALLOC(sm->path);
+ }
+
}
} else if (error != GIT_ENOTFOUND) {
goto cleanup;
}
if ((error = get_value(&value, cfg, &key, sm->name, "url")) == 0) {
- in_config = 1;
- sm->url = git__strdup(value);
- GITERR_CHECK_ALLOC(sm->url);
+ /* We would warn here if we had that API */
+ if (!looks_like_command_line_option(value)) {
+ in_config = 1;
+ sm->url = git__strdup(value);
+ GITERR_CHECK_ALLOC(sm->url);
+ }
} else if (error != GIT_ENOTFOUND) {
goto cleanup;
}
diff --git a/tests/submodule/inject_option.c b/tests/submodule/inject_option.c
new file mode 100644
index 0000000..182f088
--- /dev/null
+++ b/tests/submodule/inject_option.c
@@ -0,0 +1,80 @@
+#include "clar_libgit2.h"
+#include "posix.h"
+#include "path.h"
+#include "submodule_helpers.h"
+#include "fileops.h"
+#include "repository.h"
+
+static git_repository *g_repo = NULL;
+
+void test_submodule_inject_option__initialize(void)
+{
+ g_repo = setup_fixture_submodule_simple();
+}
+
+void test_submodule_inject_option__cleanup(void)
+{
+ cl_git_sandbox_cleanup();
+}
+
+static int find_naughty(git_submodule *sm, const char *name, void *payload)
+{
+ int *foundit = (int *) payload;
+
+ GIT_UNUSED(sm);
+
+ if (!git__strcmp("naughty", name))
+ *foundit = true;
+
+ return 0;
+}
+
+void test_submodule_inject_option__url(void)
+{
+ int foundit;
+ git_submodule *sm;
+ git_buf buf = GIT_BUF_INIT;
+
+ cl_git_pass(git_buf_joinpath(&buf, git_repository_workdir(g_repo), ".gitmodules"));
+ cl_git_rewritefile(buf.ptr,
+ "[submodule \"naughty\"]\n"
+ " path = testrepo\n"
+ " url = -u./payload\n");
+ git_buf_dispose(&buf);
+
+ /* We do want to find it, but with the appropriate field empty */
+ foundit = 0;
+ cl_git_pass(git_submodule_foreach(g_repo, find_naughty, &foundit));
+ cl_assert_equal_i(1, foundit);
+
+ cl_git_pass(git_submodule_lookup(&sm, g_repo, "naughty"));
+ cl_assert_equal_s("testrepo", git_submodule_path(sm));
+ cl_assert_equal_p(NULL, git_submodule_url(sm));
+
+ git_submodule_free(sm);
+}
+
+void test_submodule_inject_option__path(void)
+{
+ int foundit;
+ git_submodule *sm;
+ git_buf buf = GIT_BUF_INIT;
+
+ cl_git_pass(git_buf_joinpath(&buf, git_repository_workdir(g_repo), ".gitmodules"));
+ cl_git_rewritefile(buf.ptr,
+ "[submodule \"naughty\"]\n"
+ " path = --something\n"
+ " url = blah.git\n");
+ git_buf_dispose(&buf);
+
+ /* We do want to find it, but with the appropriate field empty */
+ foundit = 0;
+ cl_git_pass(git_submodule_foreach(g_repo, find_naughty, &foundit));
+ cl_assert_equal_i(1, foundit);
+
+ cl_git_pass(git_submodule_lookup(&sm, g_repo, "naughty"));
+ cl_assert_equal_s("naughty", git_submodule_path(sm));
+ cl_assert_equal_s("blah.git", git_submodule_url(sm));
+
+ git_submodule_free(sm);
+}