Merge branch 'jk/setup-gitfile-diag-fix' into seen

A regression in the error diagnosis code for invalid .git files has
been fixed, avoiding a potential NULL-pointer crash when reporting
that a .git file does not point to a valid repository.

* jk/setup-gitfile-diag-fix:
  read_gitfile_gently(): return non-repo path on error
This commit is contained in:
Junio C Hamano
2026-06-04 09:04:51 +09:00
3 changed files with 18 additions and 6 deletions

19
setup.c
View File

@@ -952,8 +952,14 @@ void read_gitfile_error_die(int error_code, const char *path, const char *dir)
* will be set to an error code and NULL will be returned. If
* return_error_code is NULL the function will die instead (for most
* cases).
*
* If the code is READ_GITFILE_ERR_NOT_A_REPO and return_error_dir is
* non-NULL, the directory to which the gitfile points will be returned
* there. The caller is responsible for freeing the resulting string.
*/
const char *read_gitfile_gently(const char *path, int *return_error_code)
const char *read_gitfile_gently_with_error_dir(const char *path,
int *return_error_code,
char **return_error_dir)
{
const int max_file_size = 1 << 20; /* 1MB */
int error_code = 0;
@@ -1018,6 +1024,8 @@ const char *read_gitfile_gently(const char *path, int *return_error_code)
}
if (!is_git_directory(dir)) {
error_code = READ_GITFILE_ERR_NOT_A_REPO;
if (return_error_dir)
*return_error_dir = xstrdup(dir);
goto cleanup_return;
}
@@ -1601,11 +1609,12 @@ static enum discovery_result setup_git_directory_gently_1(struct strbuf *dir,
int offset = dir->len, error_code = 0;
char *gitdir_path = NULL;
char *gitfile = NULL;
char *error_dst = NULL;
if (offset > min_offset)
strbuf_addch(dir, '/');
strbuf_addstr(dir, DEFAULT_GIT_DIR_ENVIRONMENT);
gitdirenv = read_gitfile_gently(dir->buf, &error_code);
gitdirenv = read_gitfile_gently_with_error_dir(dir->buf, &error_code, &error_dst);
if (!gitdirenv) {
switch (error_code) {
case READ_GITFILE_ERR_MISSING:
@@ -1629,9 +1638,11 @@ static enum discovery_result setup_git_directory_gently_1(struct strbuf *dir,
return GIT_DIR_INVALID_GITFILE;
default:
if (die_on_error)
read_gitfile_error_die(error_code, dir->buf, NULL);
else
read_gitfile_error_die(error_code, dir->buf, error_dst);
else {
free(error_dst);
return GIT_DIR_INVALID_GITFILE;
}
}
} else {
gitfile = xstrdup(dir->buf);

View File

@@ -39,7 +39,8 @@ int is_nonbare_repository_dir(struct strbuf *path);
#define READ_GITFILE_ERR_MISSING 9
#define READ_GITFILE_ERR_IS_A_DIR 10
void read_gitfile_error_die(int error_code, const char *path, const char *dir);
const char *read_gitfile_gently(const char *path, int *return_error_code);
const char *read_gitfile_gently_with_error_dir(const char *path, int *return_error_code, char **return_error_dir);
#define read_gitfile_gently(path, err) read_gitfile_gently_with_error_dir((path), (err), NULL)
#define read_gitfile(path) read_gitfile_gently((path), NULL)
const char *resolve_gitdir_gently(const char *suspect, int *return_error_code);
#define resolve_gitdir(path) resolve_gitdir_gently((path), NULL)

View File

@@ -27,7 +27,7 @@ test_expect_success 'bad setup: invalid .git file format' '
test_expect_success 'bad setup: invalid .git file path' '
echo "gitdir: $REAL.not" >.git &&
test_must_fail git rev-parse 2>.err &&
test_grep "not a git repository" .err
test_grep "not a git repository: $REAL.not" .err
'
test_expect_success 'final setup + check rev-parse --git-dir' '