Fix portability issues on Windows The new tests were not taking core.filemode into account when testing file modes after repo initialization. Fixed that and some other Windows warnings that have crept in.
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
diff --git a/src/refs.c b/src/refs.c
index cca3f3e..113cada 100644
--- a/src/refs.c
+++ b/src/refs.c
@@ -1599,7 +1599,8 @@ static int ensure_segment_validity(const char *name)
{
const char *current = name;
char prev = '\0';
- int lock_len = strlen(GIT_FILELOCK_EXTENSION);
+ const int lock_len = (int)strlen(GIT_FILELOCK_EXTENSION);
+ int segment_len;
if (*current == '.')
return -1; /* Refname starts with "." */
@@ -1620,12 +1621,14 @@ static int ensure_segment_validity(const char *name)
prev = *current;
}
+ segment_len = (int)(current - name);
+
/* A refname component can not end with ".lock" */
- if (current - name >= lock_len &&
+ if (segment_len >= lock_len &&
!memcmp(current - lock_len, GIT_FILELOCK_EXTENSION, lock_len))
return -1;
- return (int)(current - name);
+ return segment_len;
}
static bool is_all_caps_and_underscore(const char *name, size_t len)
@@ -1700,7 +1703,7 @@ int git_reference__normalize_name(
/* No empty segment is allowed when not normalizing */
if (segment_len == 0 && !normalize)
goto cleanup;
-
+
if (current[segment_len] == '\0')
break;
diff --git a/src/repository.c b/src/repository.c
index 5279d8f..e120c58 100644
--- a/src/repository.c
+++ b/src/repository.c
@@ -1043,8 +1043,11 @@ static int repo_init_structure(
static int mkdir_parent(git_buf *buf, uint32_t mode, bool skip2)
{
+ /* When making parent directories during repository initialization
+ * don't try to set gid or grant world write access
+ */
return git_futils_mkdir(
- buf->ptr, NULL, mode & ~(S_ISGID | S_IWOTH),
+ buf->ptr, NULL, mode & ~(S_ISGID | 0002),
GIT_MKDIR_PATH | GIT_MKDIR_VERIFY_DIR |
(skip2 ? GIT_MKDIR_SKIP_LAST2 : GIT_MKDIR_SKIP_LAST));
}
diff --git a/tests-clar/refs/branches/remote.c b/tests-clar/refs/branches/remote.c
index 145c318..5272d12 100644
--- a/tests-clar/refs/branches/remote.c
+++ b/tests-clar/refs/branches/remote.c
@@ -11,7 +11,7 @@ void test_refs_branches_remote__initialize(void)
{
g_repo = cl_git_sandbox_init("testrepo");
- expected_remote_name_length = strlen(expected_remote_name) + 1;
+ expected_remote_name_length = (int)strlen(expected_remote_name) + 1;
}
void test_refs_branches_remote__cleanup(void)
diff --git a/tests-clar/repo/init.c b/tests-clar/repo/init.c
index c69ea76..085d65f 100644
--- a/tests-clar/repo/init.c
+++ b/tests-clar/repo/init.c
@@ -363,10 +363,23 @@ void test_repo_init__extended_1(void)
cl_fixture_cleanup("root");
}
+static uint32_t normalize_filemode(uint32_t mode, bool core_filemode)
+{
+ /* if no filemode support, strip SETGID, exec, and low-order bits */
+
+ /* cannot use constants because on platform without SETGID, that
+ * will have been defined to zero - must use hardcoded value to
+ * clear it effectively from the expected value
+ */
+
+ return core_filemode ? mode : (mode & ~02177);
+}
+
static void assert_hooks_match(
const char *template_dir,
const char *repo_dir,
const char *hook_path,
+ bool core_filemode,
uint32_t expected_mode)
{
git_buf expected = GIT_BUF_INIT;
@@ -384,6 +397,8 @@ static void assert_hooks_match(
if (!expected_mode)
expected_mode = (uint32_t)expected_st.st_mode;
+ expected_mode = normalize_filemode(expected_mode, core_filemode);
+
cl_assert_equal_i((int)expected_mode, (int)st.st_mode);
git_buf_free(&expected);
@@ -391,7 +406,7 @@ static void assert_hooks_match(
}
static void assert_has_mode(
- const char *base, const char *path, uint32_t expected)
+ const char *base, const char *path, bool core_filemode, uint32_t expected)
{
git_buf full = GIT_BUF_INIT;
struct stat st;
@@ -400,6 +415,8 @@ static void assert_has_mode(
cl_git_pass(git_path_lstat(full.ptr, &st));
git_buf_free(&full);
+ expected = normalize_filemode(expected, core_filemode);
+
cl_assert_equal_i((int)expected, (int)st.st_mode);
}
@@ -433,11 +450,11 @@ void test_repo_init__extended_with_template(void)
assert_hooks_match(
cl_fixture("template"), git_repository_path(_repo),
- "hooks/update.sample", 0);
+ "hooks/update.sample", true, 0);
assert_hooks_match(
cl_fixture("template"), git_repository_path(_repo),
- "hooks/link.sample", 0);
+ "hooks/link.sample", true, 0);
}
void test_repo_init__extended_with_template_and_shared_mode(void)
@@ -445,6 +462,8 @@ void test_repo_init__extended_with_template_and_shared_mode(void)
git_buf expected = GIT_BUF_INIT;
git_buf actual = GIT_BUF_INIT;
git_repository_init_options opts = GIT_REPOSITORY_INIT_OPTIONS_INIT;
+ git_config *config;
+ int filemode = true;
cl_set_cleanup(&cleanup_repository, "init_shared_from_tpl");
@@ -458,6 +477,10 @@ void test_repo_init__extended_with_template_and_shared_mode(void)
cl_assert(!git_repository_is_bare(_repo));
cl_assert(!git__suffixcmp(git_repository_path(_repo), "/init_shared_from_tpl/.git/"));
+ cl_git_pass(git_repository_config(&config, _repo));
+ cl_git_pass(git_config_get_bool(&filemode, config, "core.filemode"));
+ git_config_free(config);
+
cl_git_pass(git_futils_readbuffer(
&expected, cl_fixture("template/description")));
cl_git_pass(git_futils_readbuffer(
@@ -468,17 +491,17 @@ void test_repo_init__extended_with_template_and_shared_mode(void)
git_buf_free(&expected);
git_buf_free(&actual);
- assert_has_mode(git_repository_path(_repo), "hooks",
+ assert_has_mode(git_repository_path(_repo), "hooks", filemode,
GIT_REPOSITORY_INIT_SHARED_GROUP | S_IFDIR);
- assert_has_mode(git_repository_path(_repo), "info",
+ assert_has_mode(git_repository_path(_repo), "info", filemode,
GIT_REPOSITORY_INIT_SHARED_GROUP | S_IFDIR);
- assert_has_mode(git_repository_path(_repo), "description",
+ assert_has_mode(git_repository_path(_repo), "description", filemode,
(GIT_REPOSITORY_INIT_SHARED_GROUP | S_IFREG) & ~(S_ISGID | 0111));
/* for a non-symlinked hook, it should have shared permissions now */
assert_hooks_match(
cl_fixture("template"), git_repository_path(_repo),
- "hooks/update.sample",
+ "hooks/update.sample", filemode,
(GIT_REPOSITORY_INIT_SHARED_GROUP | S_IFREG) & ~S_ISGID);
/* for a symlinked hook, the permissions still should match the
@@ -486,7 +509,7 @@ void test_repo_init__extended_with_template_and_shared_mode(void)
*/
assert_hooks_match(
cl_fixture("template"), git_repository_path(_repo),
- "hooks/link.sample", 0);
+ "hooks/link.sample", filemode, 0);
}
void test_repo_init__can_reinit_an_initialized_repository(void)