Skip to content

Commit 674791e

Browse files
derrickstoleepks-t
authored andcommitted
scalar: avoid segfault in reconfigure --all
During the latest v2.45.0 update, 'scalar reconfigure --all' started to segfault on my machine. Breaking it down via the debugger, it was faulting on a NULL reference to the_hash_algo, which is a macro pointing to the_repository->hash_algo. In my case, this is due to one of my repositories having a detached HEAD, which requires get_oid_hex() to parse that the HEAD reference is valid. Another way to cause a failure is to use the "includeIf.onbranch" config key, which will lead to a BUG() statement. My first inclination was to try to refactor cmd_reconfigure() to execute 'git for-each-repo' instead of this loop. In addition to the difficulty of executing 'scalar reconfigure' within 'git for-each-repo', it would be difficult to perform the clean-up logic for non-existent repos if we relied on that child process. Instead, I chose to move the temporary repo to be within the loop and reinstate the_repository to its old value after we are done performing logic on the current array item. Add tests to t9210-scalar.sh to test 'scalar reconfigure --all' with multiple registered repos. There are two different ways that the old use of the_repository could trigger bugs. These issues are being solved independently to be more careful about the_repository being uninitialized, but the change in this patch around the use of the_repository is still a good safety precaution. Co-authored-by: Patrick Steinhardt <[email protected]> Signed-off-by: Patrick Steinhardt <[email protected]> Signed-off-by: Derrick Stolee <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 6f73d25 commit 674791e

File tree

2 files changed

+45
-3
lines changed

2 files changed

+45
-3
lines changed

scalar.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1028,7 +1028,6 @@ static int cmd_reconfigure(int argc, const char **argv)
10281028
};
10291029
struct string_list scalar_repos = STRING_LIST_INIT_DUP;
10301030
int i, res = 0;
1031-
struct repository r = { NULL };
10321031
struct strbuf commondir = STRBUF_INIT, gitdir = STRBUF_INIT;
10331032

10341033
argc = parse_options(argc, argv, NULL, options,
@@ -1048,6 +1047,7 @@ static int cmd_reconfigure(int argc, const char **argv)
10481047

10491048
for (i = 0; i < scalar_repos.nr; i++) {
10501049
int succeeded = 0;
1050+
struct repository *old_repo, r = { NULL };
10511051
const char *dir = scalar_repos.items[i].string;
10521052

10531053
strbuf_reset(&commondir);
@@ -1095,14 +1095,18 @@ static int cmd_reconfigure(int argc, const char **argv)
10951095

10961096
git_config_clear();
10971097

1098+
if (repo_init(&r, gitdir.buf, commondir.buf))
1099+
goto loop_end;
1100+
1101+
old_repo = the_repository;
10981102
the_repository = &r;
1099-
r.commondir = commondir.buf;
1100-
r.gitdir = gitdir.buf;
11011103

11021104
if (set_recommended_config(1) >= 0 &&
11031105
toggle_maintenance(1) >= 0)
11041106
succeeded = 1;
11051107

1108+
the_repository = old_repo;
1109+
11061110
loop_end:
11071111
if (!succeeded) {
11081112
res = -1;

t/t9210-scalar.sh

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,44 @@ test_expect_success 'scalar reconfigure' '
190190
test_subcommand git maintenance start <reconfigure
191191
'
192192

193+
test_expect_success 'scalar reconfigure --all with includeIf.onbranch' '
194+
repos="two three four" &&
195+
for num in $repos
196+
do
197+
git init $num/src &&
198+
scalar register $num/src &&
199+
git -C $num/src config includeif."onbranch:foo".path something &&
200+
git -C $num/src config core.preloadIndex false || return 1
201+
done &&
202+
203+
scalar reconfigure --all &&
204+
205+
for num in $repos
206+
do
207+
test true = "$(git -C $num/src config core.preloadIndex)" || return 1
208+
done
209+
'
210+
211+
test_expect_success 'scalar reconfigure --all with detached HEADs' '
212+
repos="two three four" &&
213+
for num in $repos
214+
do
215+
rm -rf $num/src &&
216+
git init $num/src &&
217+
scalar register $num/src &&
218+
git -C $num/src config core.preloadIndex false &&
219+
test_commit -C $num/src initial &&
220+
git -C $num/src switch --detach HEAD || return 1
221+
done &&
222+
223+
scalar reconfigure --all &&
224+
225+
for num in $repos
226+
do
227+
test true = "$(git -C $num/src config core.preloadIndex)" || return 1
228+
done
229+
'
230+
193231
test_expect_success '`reconfigure -a` removes stale config entries' '
194232
git init stale/src &&
195233
scalar register stale &&

0 commit comments

Comments
 (0)