Skip to content

Commit 2846ef3

Browse files
committed
Merge branch 'js/realpath-pathdup-fix' into maint
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. ... and then to down to 'maint'. * 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
2 parents f989ac2 + ce83ead commit 2846ef3

File tree

10 files changed

+26
-18
lines changed

10 files changed

+26
-18
lines changed

abspath.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -214,12 +214,12 @@ const char *real_path_if_valid(const char *path)
214214
return strbuf_realpath(&realpath, path, 0);
215215
}
216216

217-
char *real_pathdup(const char *path)
217+
char *real_pathdup(const char *path, int die_on_error)
218218
{
219219
struct strbuf realpath = STRBUF_INIT;
220220
char *retval = NULL;
221221

222-
if (strbuf_realpath(&realpath, path, 0))
222+
if (strbuf_realpath(&realpath, path, die_on_error))
223223
retval = strbuf_detach(&realpath, NULL);
224224

225225
strbuf_release(&realpath);

builtin/init-db.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -338,7 +338,7 @@ int init_db(const char *git_dir, const char *real_git_dir,
338338
{
339339
int reinit;
340340
int exist_ok = flags & INIT_DB_EXIST_OK;
341-
char *original_git_dir = real_pathdup(git_dir);
341+
char *original_git_dir = real_pathdup(git_dir, 1);
342342

343343
if (real_git_dir) {
344344
struct stat st;
@@ -489,7 +489,7 @@ int cmd_init_db(int argc, const char **argv, const char *prefix)
489489
argc = parse_options(argc, argv, prefix, init_db_options, init_db_usage, 0);
490490

491491
if (real_git_dir && !is_absolute_path(real_git_dir))
492-
real_git_dir = real_pathdup(real_git_dir);
492+
real_git_dir = real_pathdup(real_git_dir, 1);
493493

494494
if (argc == 1) {
495495
int mkdir_tried = 0;
@@ -560,7 +560,7 @@ int cmd_init_db(int argc, const char **argv, const char *prefix)
560560
const char *git_dir_parent = strrchr(git_dir, '/');
561561
if (git_dir_parent) {
562562
char *rel = xstrndup(git_dir, git_dir_parent - git_dir);
563-
git_work_tree_cfg = real_pathdup(rel);
563+
git_work_tree_cfg = real_pathdup(rel, 1);
564564
free(rel);
565565
}
566566
if (!git_work_tree_cfg)

cache.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1109,7 +1109,7 @@ char *strbuf_realpath(struct strbuf *resolved, const char *path,
11091109
int die_on_error);
11101110
const char *real_path(const char *path);
11111111
const char *real_path_if_valid(const char *path);
1112-
char *real_pathdup(const char *path);
1112+
char *real_pathdup(const char *path, int die_on_error);
11131113
const char *absolute_path(const char *path);
11141114
char *absolute_pathdup(const char *path);
11151115
const char *remove_leading_path(const char *in, const char *prefix);

dir.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2730,8 +2730,8 @@ void connect_work_tree_and_git_dir(const char *work_tree_, const char *git_dir_)
27302730
{
27312731
struct strbuf file_name = STRBUF_INIT;
27322732
struct strbuf rel_path = STRBUF_INIT;
2733-
char *git_dir = real_pathdup(git_dir_);
2734-
char *work_tree = real_pathdup(work_tree_);
2733+
char *git_dir = real_pathdup(git_dir_, 1);
2734+
char *work_tree = real_pathdup(work_tree_, 1);
27352735

27362736
/* Update gitfile */
27372737
strbuf_addf(&file_name, "%s/.git", work_tree);

environment.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,7 @@ void set_git_work_tree(const char *new_work_tree)
259259
return;
260260
}
261261
git_work_tree_initialized = 1;
262-
work_tree = real_pathdup(new_work_tree);
262+
work_tree = real_pathdup(new_work_tree, 1);
263263
}
264264

265265
const char *get_git_work_tree(void)

setup.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -698,7 +698,7 @@ static const char *setup_discovered_git_dir(const char *gitdir,
698698
/* --work-tree is set without --git-dir; use discovered one */
699699
if (getenv(GIT_WORK_TREE_ENVIRONMENT) || git_work_tree_cfg) {
700700
if (offset != cwd->len && !is_absolute_path(gitdir))
701-
gitdir = real_pathdup(gitdir);
701+
gitdir = real_pathdup(gitdir, 1);
702702
if (chdir(cwd->buf))
703703
die_errno("Could not come back to cwd");
704704
return setup_explicit_git_dir(gitdir, cwd, nongit_ok);
@@ -806,7 +806,7 @@ static int canonicalize_ceiling_entry(struct string_list_item *item,
806806
/* Keep entry but do not canonicalize it */
807807
return 1;
808808
} else {
809-
char *real_path = real_pathdup(ceil);
809+
char *real_path = real_pathdup(ceil, 0);
810810
if (!real_path) {
811811
return 0;
812812
}

submodule.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1403,7 +1403,7 @@ static void relocate_single_git_dir_into_superproject(const char *prefix,
14031403
/* If it is an actual gitfile, it doesn't need migration. */
14041404
return;
14051405

1406-
real_old_git_dir = real_pathdup(old_git_dir);
1406+
real_old_git_dir = real_pathdup(old_git_dir, 1);
14071407

14081408
sub = submodule_from_path(null_sha1, path);
14091409
if (!sub)
@@ -1412,7 +1412,7 @@ static void relocate_single_git_dir_into_superproject(const char *prefix,
14121412
new_git_dir = git_path("modules/%s", sub->name);
14131413
if (safe_create_leading_directories_const(new_git_dir) < 0)
14141414
die(_("could not create directory '%s'"), new_git_dir);
1415-
real_new_git_dir = real_pathdup(new_git_dir);
1415+
real_new_git_dir = real_pathdup(new_git_dir, 1);
14161416

14171417
if (!prefix)
14181418
prefix = get_super_prefix();
@@ -1472,14 +1472,14 @@ void absorb_git_dir_into_superproject(const char *prefix,
14721472
new_git_dir = git_path("modules/%s", sub->name);
14731473
if (safe_create_leading_directories_const(new_git_dir) < 0)
14741474
die(_("could not create directory '%s'"), new_git_dir);
1475-
real_new_git_dir = real_pathdup(new_git_dir);
1475+
real_new_git_dir = real_pathdup(new_git_dir, 1);
14761476
connect_work_tree_and_git_dir(path, real_new_git_dir);
14771477

14781478
free(real_new_git_dir);
14791479
} else {
14801480
/* Is it already absorbed into the superprojects git dir? */
1481-
char *real_sub_git_dir = real_pathdup(sub_git_dir);
1482-
char *real_common_git_dir = real_pathdup(get_git_common_dir());
1481+
char *real_sub_git_dir = real_pathdup(sub_git_dir, 1);
1482+
char *real_common_git_dir = real_pathdup(get_git_common_dir(), 1);
14831483

14841484
if (!starts_with(real_sub_git_dir, real_common_git_dir))
14851485
relocate_single_git_dir_into_superproject(prefix, path);

t/t1501-work-tree.sh

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -423,4 +423,12 @@ test_expect_success '$GIT_WORK_TREE overrides $GIT_DIR/common' '
423423
)
424424
'
425425

426+
test_expect_success 'error out gracefully on invalid $GIT_WORK_TREE' '
427+
(
428+
GIT_WORK_TREE=/.invalid/work/tree &&
429+
export GIT_WORK_TREE &&
430+
test_expect_code 128 git rev-parse
431+
)
432+
'
433+
426434
test_done

transport.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1221,7 +1221,7 @@ static int refs_from_alternate_cb(struct alternate_object_database *e,
12211221
const struct ref *extra;
12221222
struct alternate_refs_data *cb = data;
12231223

1224-
other = real_pathdup(e->path);
1224+
other = real_pathdup(e->path, 1);
12251225
len = strlen(other);
12261226

12271227
while (other[len-1] == '/')

worktree.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,7 @@ struct worktree *find_worktree(struct worktree **list,
255255
return wt;
256256

257257
arg = prefix_filename(prefix, strlen(prefix), arg);
258-
path = real_pathdup(arg);
258+
path = real_pathdup(arg, 1);
259259
for (; *list; list++)
260260
if (!fspathcmp(path, real_path((*list)->path)))
261261
break;

0 commit comments

Comments
 (0)