mirror of
https://github.com/git/git.git
synced 2024-11-27 12:03:55 +08:00
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>
This commit is contained in:
parent
8b5157e407
commit
47fc52e287
20
refs.c
20
refs.c
@ -992,7 +992,7 @@ int create_symref(const char *ref_target, const char *refs_heads_master,
|
||||
const char *lockpath;
|
||||
char ref[1000];
|
||||
int fd, len, written;
|
||||
const char *git_HEAD = git_path("%s", ref_target);
|
||||
char *git_HEAD = xstrdup(git_path("%s", ref_target));
|
||||
unsigned char old_sha1[20], new_sha1[20];
|
||||
|
||||
if (logmsg && read_ref(ref_target, old_sha1))
|
||||
@ -1010,36 +1010,38 @@ int create_symref(const char *ref_target, const char *refs_heads_master,
|
||||
len = snprintf(ref, sizeof(ref), "ref: %s\n", refs_heads_master);
|
||||
if (sizeof(ref) <= len) {
|
||||
error("refname too long: %s", refs_heads_master);
|
||||
return -1;
|
||||
goto error_free_return;
|
||||
}
|
||||
lockpath = mkpath("%s.lock", git_HEAD);
|
||||
fd = open(lockpath, O_CREAT | O_EXCL | O_WRONLY, 0666);
|
||||
if (fd < 0) {
|
||||
error("Unable to open %s for writing", lockpath);
|
||||
return -5;
|
||||
goto error_free_return;
|
||||
}
|
||||
written = write_in_full(fd, ref, len);
|
||||
close(fd);
|
||||
if (written != len) {
|
||||
unlink(lockpath);
|
||||
error("Unable to write to %s", lockpath);
|
||||
return -2;
|
||||
goto error_unlink_return;
|
||||
}
|
||||
if (rename(lockpath, git_HEAD) < 0) {
|
||||
unlink(lockpath);
|
||||
error("Unable to create %s", git_HEAD);
|
||||
return -3;
|
||||
goto error_unlink_return;
|
||||
}
|
||||
if (adjust_shared_perm(git_HEAD)) {
|
||||
unlink(lockpath);
|
||||
error("Unable to fix permissions on %s", lockpath);
|
||||
return -4;
|
||||
error_unlink_return:
|
||||
unlink(lockpath);
|
||||
error_free_return:
|
||||
free(git_HEAD);
|
||||
return -1;
|
||||
}
|
||||
|
||||
done:
|
||||
if (logmsg && !read_ref(refs_heads_master, new_sha1))
|
||||
log_ref_write(ref_target, old_sha1, new_sha1, logmsg);
|
||||
|
||||
free(git_HEAD);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user