Skip to content

Commit 47fc52e

Browse files
author
Junio C Hamano
committed
create_symref(): do not assume pathname from git_path() persists long enough
Being lazy to rely on the cycling N buffers mkpath() and friends return is nice in general, but it makes it too easy to introduce new bugs that are "mysterious". Introduction of read_ref() in create_symref() after calling git_path() to get the git_HEAD value (i.e. the path to create a new symref at) consumed more than the available buffers and broke a later call to mkpath() that derives lockpath from it. Signed-off-by: Junio C Hamano <junkio@cox.net>
1 parent 8b5157e commit 47fc52e

File tree

1 file changed

+11
-9
lines changed

1 file changed

+11
-9
lines changed

refs.c

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -992,7 +992,7 @@ int create_symref(const char *ref_target, const char *refs_heads_master,
992992
const char *lockpath;
993993
char ref[1000];
994994
int fd, len, written;
995-
const char *git_HEAD = git_path("%s", ref_target);
995+
char *git_HEAD = xstrdup(git_path("%s", ref_target));
996996
unsigned char old_sha1[20], new_sha1[20];
997997

998998
if (logmsg && read_ref(ref_target, old_sha1))
@@ -1010,36 +1010,38 @@ int create_symref(const char *ref_target, const char *refs_heads_master,
10101010
len = snprintf(ref, sizeof(ref), "ref: %s\n", refs_heads_master);
10111011
if (sizeof(ref) <= len) {
10121012
error("refname too long: %s", refs_heads_master);
1013-
return -1;
1013+
goto error_free_return;
10141014
}
10151015
lockpath = mkpath("%s.lock", git_HEAD);
10161016
fd = open(lockpath, O_CREAT | O_EXCL | O_WRONLY, 0666);
10171017
if (fd < 0) {
10181018
error("Unable to open %s for writing", lockpath);
1019-
return -5;
1019+
goto error_free_return;
10201020
}
10211021
written = write_in_full(fd, ref, len);
10221022
close(fd);
10231023
if (written != len) {
1024-
unlink(lockpath);
10251024
error("Unable to write to %s", lockpath);
1026-
return -2;
1025+
goto error_unlink_return;
10271026
}
10281027
if (rename(lockpath, git_HEAD) < 0) {
1029-
unlink(lockpath);
10301028
error("Unable to create %s", git_HEAD);
1031-
return -3;
1029+
goto error_unlink_return;
10321030
}
10331031
if (adjust_shared_perm(git_HEAD)) {
1034-
unlink(lockpath);
10351032
error("Unable to fix permissions on %s", lockpath);
1036-
return -4;
1033+
error_unlink_return:
1034+
unlink(lockpath);
1035+
error_free_return:
1036+
free(git_HEAD);
1037+
return -1;
10371038
}
10381039

10391040
done:
10401041
if (logmsg && !read_ref(refs_heads_master, new_sha1))
10411042
log_ref_write(ref_target, old_sha1, new_sha1, logmsg);
10421043

1044+
free(git_HEAD);
10431045
return 0;
10441046
}
10451047

0 commit comments

Comments
 (0)