Merge branch 'js/realpath-pathdup-fix'
Git v2.12 was shipped with an embarrassing breakage where various operations that verify paths given from the user stopped dying when seeing an issue, and instead later triggering segfault. * js/realpath-pathdup-fix: real_pathdup(): fix callsites that wanted it to die on error t1501: demonstrate NULL pointer access with invalid GIT_WORK_TREE
This commit is contained in:
commit
ba37c92df9
@ -214,12 +214,12 @@ const char *real_path_if_valid(const char *path)
|
||||
return strbuf_realpath(&realpath, path, 0);
|
||||
}
|
||||
|
||||
char *real_pathdup(const char *path)
|
||||
char *real_pathdup(const char *path, int die_on_error)
|
||||
{
|
||||
struct strbuf realpath = STRBUF_INIT;
|
||||
char *retval = NULL;
|
||||
|
||||
if (strbuf_realpath(&realpath, path, 0))
|
||||
if (strbuf_realpath(&realpath, path, die_on_error))
|
||||
retval = strbuf_detach(&realpath, NULL);
|
||||
|
||||
strbuf_release(&realpath);
|
||||
|
@ -338,7 +338,7 @@ int init_db(const char *git_dir, const char *real_git_dir,
|
||||
{
|
||||
int reinit;
|
||||
int exist_ok = flags & INIT_DB_EXIST_OK;
|
||||
char *original_git_dir = real_pathdup(git_dir);
|
||||
char *original_git_dir = real_pathdup(git_dir, 1);
|
||||
|
||||
if (real_git_dir) {
|
||||
struct stat st;
|
||||
@ -489,7 +489,7 @@ int cmd_init_db(int argc, const char **argv, const char *prefix)
|
||||
argc = parse_options(argc, argv, prefix, init_db_options, init_db_usage, 0);
|
||||
|
||||
if (real_git_dir && !is_absolute_path(real_git_dir))
|
||||
real_git_dir = real_pathdup(real_git_dir);
|
||||
real_git_dir = real_pathdup(real_git_dir, 1);
|
||||
|
||||
if (argc == 1) {
|
||||
int mkdir_tried = 0;
|
||||
@ -560,7 +560,7 @@ int cmd_init_db(int argc, const char **argv, const char *prefix)
|
||||
const char *git_dir_parent = strrchr(git_dir, '/');
|
||||
if (git_dir_parent) {
|
||||
char *rel = xstrndup(git_dir, git_dir_parent - git_dir);
|
||||
git_work_tree_cfg = real_pathdup(rel);
|
||||
git_work_tree_cfg = real_pathdup(rel, 1);
|
||||
free(rel);
|
||||
}
|
||||
if (!git_work_tree_cfg)
|
||||
|
2
cache.h
2
cache.h
@ -1150,7 +1150,7 @@ char *strbuf_realpath(struct strbuf *resolved, const char *path,
|
||||
int die_on_error);
|
||||
const char *real_path(const char *path);
|
||||
const char *real_path_if_valid(const char *path);
|
||||
char *real_pathdup(const char *path);
|
||||
char *real_pathdup(const char *path, int die_on_error);
|
||||
const char *absolute_path(const char *path);
|
||||
char *absolute_pathdup(const char *path);
|
||||
const char *remove_leading_path(const char *in, const char *prefix);
|
||||
|
4
dir.c
4
dir.c
@ -2730,8 +2730,8 @@ void connect_work_tree_and_git_dir(const char *work_tree_, const char *git_dir_)
|
||||
{
|
||||
struct strbuf file_name = STRBUF_INIT;
|
||||
struct strbuf rel_path = STRBUF_INIT;
|
||||
char *git_dir = real_pathdup(git_dir_);
|
||||
char *work_tree = real_pathdup(work_tree_);
|
||||
char *git_dir = real_pathdup(git_dir_, 1);
|
||||
char *work_tree = real_pathdup(work_tree_, 1);
|
||||
|
||||
/* Update gitfile */
|
||||
strbuf_addf(&file_name, "%s/.git", work_tree);
|
||||
|
@ -259,7 +259,7 @@ void set_git_work_tree(const char *new_work_tree)
|
||||
return;
|
||||
}
|
||||
git_work_tree_initialized = 1;
|
||||
work_tree = real_pathdup(new_work_tree);
|
||||
work_tree = real_pathdup(new_work_tree, 1);
|
||||
}
|
||||
|
||||
const char *get_git_work_tree(void)
|
||||
|
4
setup.c
4
setup.c
@ -698,7 +698,7 @@ static const char *setup_discovered_git_dir(const char *gitdir,
|
||||
/* --work-tree is set without --git-dir; use discovered one */
|
||||
if (getenv(GIT_WORK_TREE_ENVIRONMENT) || git_work_tree_cfg) {
|
||||
if (offset != cwd->len && !is_absolute_path(gitdir))
|
||||
gitdir = real_pathdup(gitdir);
|
||||
gitdir = real_pathdup(gitdir, 1);
|
||||
if (chdir(cwd->buf))
|
||||
die_errno("Could not come back to cwd");
|
||||
return setup_explicit_git_dir(gitdir, cwd, nongit_ok);
|
||||
@ -806,7 +806,7 @@ static int canonicalize_ceiling_entry(struct string_list_item *item,
|
||||
/* Keep entry but do not canonicalize it */
|
||||
return 1;
|
||||
} else {
|
||||
char *real_path = real_pathdup(ceil);
|
||||
char *real_path = real_pathdup(ceil, 0);
|
||||
if (!real_path) {
|
||||
return 0;
|
||||
}
|
||||
|
10
submodule.c
10
submodule.c
@ -1403,7 +1403,7 @@ static void relocate_single_git_dir_into_superproject(const char *prefix,
|
||||
/* If it is an actual gitfile, it doesn't need migration. */
|
||||
return;
|
||||
|
||||
real_old_git_dir = real_pathdup(old_git_dir);
|
||||
real_old_git_dir = real_pathdup(old_git_dir, 1);
|
||||
|
||||
sub = submodule_from_path(null_sha1, path);
|
||||
if (!sub)
|
||||
@ -1412,7 +1412,7 @@ static void relocate_single_git_dir_into_superproject(const char *prefix,
|
||||
new_git_dir = git_path("modules/%s", sub->name);
|
||||
if (safe_create_leading_directories_const(new_git_dir) < 0)
|
||||
die(_("could not create directory '%s'"), new_git_dir);
|
||||
real_new_git_dir = real_pathdup(new_git_dir);
|
||||
real_new_git_dir = real_pathdup(new_git_dir, 1);
|
||||
|
||||
if (!prefix)
|
||||
prefix = get_super_prefix();
|
||||
@ -1472,14 +1472,14 @@ void absorb_git_dir_into_superproject(const char *prefix,
|
||||
new_git_dir = git_path("modules/%s", sub->name);
|
||||
if (safe_create_leading_directories_const(new_git_dir) < 0)
|
||||
die(_("could not create directory '%s'"), new_git_dir);
|
||||
real_new_git_dir = real_pathdup(new_git_dir);
|
||||
real_new_git_dir = real_pathdup(new_git_dir, 1);
|
||||
connect_work_tree_and_git_dir(path, real_new_git_dir);
|
||||
|
||||
free(real_new_git_dir);
|
||||
} else {
|
||||
/* Is it already absorbed into the superprojects git dir? */
|
||||
char *real_sub_git_dir = real_pathdup(sub_git_dir);
|
||||
char *real_common_git_dir = real_pathdup(get_git_common_dir());
|
||||
char *real_sub_git_dir = real_pathdup(sub_git_dir, 1);
|
||||
char *real_common_git_dir = real_pathdup(get_git_common_dir(), 1);
|
||||
|
||||
if (!starts_with(real_sub_git_dir, real_common_git_dir))
|
||||
relocate_single_git_dir_into_superproject(prefix, path);
|
||||
|
@ -423,4 +423,12 @@ test_expect_success '$GIT_WORK_TREE overrides $GIT_DIR/common' '
|
||||
)
|
||||
'
|
||||
|
||||
test_expect_success 'error out gracefully on invalid $GIT_WORK_TREE' '
|
||||
(
|
||||
GIT_WORK_TREE=/.invalid/work/tree &&
|
||||
export GIT_WORK_TREE &&
|
||||
test_expect_code 128 git rev-parse
|
||||
)
|
||||
'
|
||||
|
||||
test_done
|
||||
|
@ -255,7 +255,7 @@ struct worktree *find_worktree(struct worktree **list,
|
||||
return wt;
|
||||
|
||||
arg = prefix_filename(prefix, strlen(prefix), arg);
|
||||
path = real_pathdup(arg);
|
||||
path = real_pathdup(arg, 1);
|
||||
for (; *list; list++)
|
||||
if (!fspathcmp(path, real_path((*list)->path)))
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user