Merge pull request #3434 from ethomson/reservednames Win32 Reserved names: don't reserve names outside the working directory
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 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236
diff --git a/src/repository.c b/src/repository.c
index d0bf7dc..77145cf 100644
--- a/src/repository.c
+++ b/src/repository.c
@@ -908,12 +908,28 @@ bool git_repository__reserved_names(
buf->size = git_repository__reserved_names_win32[i].size;
}
- /* Try to add any repo-specific reserved names */
+ /* Try to add any repo-specific reserved names - the gitlink file
+ * within a submodule or the repository (if the repository directory
+ * is beneath the workdir). These are typically `.git`, but should
+ * be protected in case they are not. Note, repo and workdir paths
+ * are always prettified to end in `/`, so a prefixcmp is safe.
+ */
if (!repo->is_bare) {
- const char *reserved_path = repo->path_gitlink ?
- repo->path_gitlink : repo->path_repository;
+ int (*prefixcmp)(const char *, const char *);
+ int error, ignorecase;
- if (reserved_names_add8dot3(repo, reserved_path) < 0)
+ error = git_repository__cvar(
+ &ignorecase, repo, GIT_CVAR_IGNORECASE);
+ prefixcmp = (error || ignorecase) ? git__prefixcmp_icase :
+ git__prefixcmp;
+
+ if (repo->path_gitlink &&
+ reserved_names_add8dot3(repo, repo->path_gitlink) < 0)
+ goto on_error;
+
+ if (repo->path_repository &&
+ prefixcmp(repo->path_repository, repo->workdir) == 0 &&
+ reserved_names_add8dot3(repo, repo->path_repository) < 0)
goto on_error;
}
}
diff --git a/tests/repo/reservedname.c b/tests/repo/reservedname.c
index faea0cc..2a5b382 100644
--- a/tests/repo/reservedname.c
+++ b/tests/repo/reservedname.c
@@ -106,3 +106,27 @@ void test_repo_reservedname__submodule_pointer(void)
git_repository_free(sub_repo);
#endif
}
+
+/* Like the `submodule_pointer` test (above), this ensures that we do not
+ * follow the gitlink to the submodule's repository location and treat that
+ * as a reserved name. This tests at an initial submodule update, where the
+ * submodule repo is being created.
+ */
+void test_repo_reservedname__submodule_pointer_during_create(void)
+{
+ git_repository *repo;
+ git_submodule *sm;
+ git_submodule_update_options update_options = GIT_SUBMODULE_UPDATE_OPTIONS_INIT;
+ git_buf url = GIT_BUF_INIT;
+
+ repo = setup_fixture_super();
+
+ cl_git_pass(git_buf_joinpath(&url, clar_sandbox_path(), "sub.git"));
+ cl_repo_set_string(repo, "submodule.sub.url", url.ptr);
+
+ cl_git_pass(git_submodule_lookup(&sm, repo, "sub"));
+ cl_git_pass(git_submodule_update(sm, 1, &update_options));
+
+ git_submodule_free(sm);
+ git_buf_free(&url);
+}
diff --git a/tests/resources/sub.git/HEAD b/tests/resources/sub.git/HEAD
new file mode 100644
index 0000000..cb089cd
--- /dev/null
+++ b/tests/resources/sub.git/HEAD
@@ -0,0 +1 @@
+ref: refs/heads/master
diff --git a/tests/resources/sub.git/config b/tests/resources/sub.git/config
new file mode 100644
index 0000000..78387c5
--- /dev/null
+++ b/tests/resources/sub.git/config
@@ -0,0 +1,8 @@
+[core]
+ repositoryformatversion = 0
+ filemode = false
+ bare = false
+ logallrefupdates = true
+ symlinks = false
+ ignorecase = true
+ hideDotFiles = dotGitOnly
diff --git a/tests/resources/sub.git/index b/tests/resources/sub.git/index
new file mode 100644
index 0000000..54be69e
Binary files /dev/null and b/tests/resources/sub.git/index differ
diff --git a/tests/resources/sub.git/logs/HEAD b/tests/resources/sub.git/logs/HEAD
new file mode 100644
index 0000000..f636268
--- /dev/null
+++ b/tests/resources/sub.git/logs/HEAD
@@ -0,0 +1 @@
+0000000000000000000000000000000000000000 b7a59b3f4ea13b985f8a1e0d3757d5cd3331add8 Edward Thomson <ethomson@microsoft.com> 1442522322 -0400 commit (initial): Initial revision
diff --git a/tests/resources/sub.git/logs/refs/heads/master b/tests/resources/sub.git/logs/refs/heads/master
new file mode 100644
index 0000000..f636268
--- /dev/null
+++ b/tests/resources/sub.git/logs/refs/heads/master
@@ -0,0 +1 @@
+0000000000000000000000000000000000000000 b7a59b3f4ea13b985f8a1e0d3757d5cd3331add8 Edward Thomson <ethomson@microsoft.com> 1442522322 -0400 commit (initial): Initial revision
diff --git a/tests/resources/sub.git/objects/10/ddd6d257e01349d514541981aeecea6b2e741d b/tests/resources/sub.git/objects/10/ddd6d257e01349d514541981aeecea6b2e741d
new file mode 100644
index 0000000..a095b3f
Binary files /dev/null and b/tests/resources/sub.git/objects/10/ddd6d257e01349d514541981aeecea6b2e741d differ
diff --git a/tests/resources/sub.git/objects/17/6a458f94e0ea5272ce67c36bf30b6be9caf623 b/tests/resources/sub.git/objects/17/6a458f94e0ea5272ce67c36bf30b6be9caf623
new file mode 100644
index 0000000..ef83166
Binary files /dev/null and b/tests/resources/sub.git/objects/17/6a458f94e0ea5272ce67c36bf30b6be9caf623 differ
diff --git a/tests/resources/sub.git/objects/94/c7d78d85c933d1d95b56bc2de01833ba8559fb b/tests/resources/sub.git/objects/94/c7d78d85c933d1d95b56bc2de01833ba8559fb
new file mode 100644
index 0000000..9adc11d
Binary files /dev/null and b/tests/resources/sub.git/objects/94/c7d78d85c933d1d95b56bc2de01833ba8559fb differ
diff --git a/tests/resources/sub.git/objects/b7/a59b3f4ea13b985f8a1e0d3757d5cd3331add8 b/tests/resources/sub.git/objects/b7/a59b3f4ea13b985f8a1e0d3757d5cd3331add8
new file mode 100644
index 0000000..221b55d
Binary files /dev/null and b/tests/resources/sub.git/objects/b7/a59b3f4ea13b985f8a1e0d3757d5cd3331add8 differ
diff --git a/tests/resources/sub.git/objects/d0/ee23c41b28746d7e822511d7838bce784ae773 b/tests/resources/sub.git/objects/d0/ee23c41b28746d7e822511d7838bce784ae773
new file mode 100644
index 0000000..d9bb9c8
Binary files /dev/null and b/tests/resources/sub.git/objects/d0/ee23c41b28746d7e822511d7838bce784ae773 differ
diff --git a/tests/resources/sub.git/refs/heads/master b/tests/resources/sub.git/refs/heads/master
new file mode 100644
index 0000000..0e4d6e2
--- /dev/null
+++ b/tests/resources/sub.git/refs/heads/master
@@ -0,0 +1 @@
+b7a59b3f4ea13b985f8a1e0d3757d5cd3331add8
diff --git a/tests/resources/super/.gitted/COMMIT_EDITMSG b/tests/resources/super/.gitted/COMMIT_EDITMSG
new file mode 100644
index 0000000..e2d6b89
--- /dev/null
+++ b/tests/resources/super/.gitted/COMMIT_EDITMSG
@@ -0,0 +1 @@
+submodule
diff --git a/tests/resources/super/.gitted/HEAD b/tests/resources/super/.gitted/HEAD
new file mode 100644
index 0000000..cb089cd
--- /dev/null
+++ b/tests/resources/super/.gitted/HEAD
@@ -0,0 +1 @@
+ref: refs/heads/master
diff --git a/tests/resources/super/.gitted/config b/tests/resources/super/.gitted/config
new file mode 100644
index 0000000..06a8b77
--- /dev/null
+++ b/tests/resources/super/.gitted/config
@@ -0,0 +1,10 @@
+[core]
+ repositoryformatversion = 0
+ filemode = false
+ bare = false
+ logallrefupdates = true
+ symlinks = false
+ ignorecase = true
+ hideDotFiles = dotGitOnly
+[submodule "sub"]
+ url = ../sub.git
diff --git a/tests/resources/super/.gitted/index b/tests/resources/super/.gitted/index
new file mode 100644
index 0000000..cc2ffff
Binary files /dev/null and b/tests/resources/super/.gitted/index differ
diff --git a/tests/resources/super/.gitted/objects/51/589c218bf77a8da9e9d8dbc097d76a742726c4 b/tests/resources/super/.gitted/objects/51/589c218bf77a8da9e9d8dbc097d76a742726c4
new file mode 100644
index 0000000..727d3a6
Binary files /dev/null and b/tests/resources/super/.gitted/objects/51/589c218bf77a8da9e9d8dbc097d76a742726c4 differ
diff --git a/tests/resources/super/.gitted/objects/79/d0d58ca6aa1688a073d280169908454cad5b91 b/tests/resources/super/.gitted/objects/79/d0d58ca6aa1688a073d280169908454cad5b91
new file mode 100644
index 0000000..7fd889d
Binary files /dev/null and b/tests/resources/super/.gitted/objects/79/d0d58ca6aa1688a073d280169908454cad5b91 differ
diff --git a/tests/resources/super/.gitted/objects/d7/57768b570a83e80d02edcc1032db14573e5034 b/tests/resources/super/.gitted/objects/d7/57768b570a83e80d02edcc1032db14573e5034
new file mode 100644
index 0000000..f26c68c
Binary files /dev/null and b/tests/resources/super/.gitted/objects/d7/57768b570a83e80d02edcc1032db14573e5034 differ
diff --git a/tests/resources/super/.gitted/refs/heads/master b/tests/resources/super/.gitted/refs/heads/master
new file mode 100644
index 0000000..663a9dc
--- /dev/null
+++ b/tests/resources/super/.gitted/refs/heads/master
@@ -0,0 +1 @@
+79d0d58ca6aa1688a073d280169908454cad5b91
diff --git a/tests/resources/super/gitmodules b/tests/resources/super/gitmodules
new file mode 100644
index 0000000..a3d8f7f
--- /dev/null
+++ b/tests/resources/super/gitmodules
@@ -0,0 +1,3 @@
+[submodule "sub"]
+ path = sub
+ url = ../sub.git
diff --git a/tests/submodule/submodule_helpers.c b/tests/submodule/submodule_helpers.c
index 1dc6872..cde69d9 100644
--- a/tests/submodule/submodule_helpers.c
+++ b/tests/submodule/submodule_helpers.c
@@ -126,6 +126,22 @@ git_repository *setup_fixture_submod2(void)
return repo;
}
+git_repository *setup_fixture_super(void)
+{
+ git_repository *repo = cl_git_sandbox_init("super");
+
+ cl_fixture_sandbox("sub.git");
+ p_mkdir("super/sub", 0777);
+
+ rewrite_gitmodules(git_repository_workdir(repo));
+
+ cl_set_cleanup(cleanup_fixture_submodules, "sub.git");
+
+ cl_git_pass(git_repository_reinit_filesystem(repo, 1));
+
+ return repo;
+}
+
git_repository *setup_fixture_submodule_simple(void)
{
git_repository *repo = cl_git_sandbox_init("submodule_simple");
diff --git a/tests/submodule/submodule_helpers.h b/tests/submodule/submodule_helpers.h
index 1493f24..1191ab3 100644
--- a/tests/submodule/submodule_helpers.h
+++ b/tests/submodule/submodule_helpers.h
@@ -4,6 +4,7 @@ extern void rewrite_gitmodules(const char *workdir);
extern git_repository *setup_fixture_submodules(void);
extern git_repository *setup_fixture_submod2(void);
extern git_repository *setup_fixture_submodule_simple(void);
+extern git_repository *setup_fixture_super(void);
extern unsigned int get_submodule_status(git_repository *, const char *);