summaryrefslogtreecommitdiff
path: root/refs.c
diff options
context:
space:
mode:
authorJunio C Hamano <junkio@cox.net>2007-01-27 01:49:00 (GMT)
committerJunio C Hamano <junkio@cox.net>2007-01-28 10:16:46 (GMT)
commit47fc52e2876ed3a54cd4b77e0b0c4875fa3317b8 (patch)
tree48ed1a524b2a77a0608fc22147334717b3e18342 /refs.c
parent8b5157e40718a2ee1d645c342d93df4e66335479 (diff)
downloadgit-47fc52e2876ed3a54cd4b77e0b0c4875fa3317b8.zip
git-47fc52e2876ed3a54cd4b77e0b0c4875fa3317b8.tar.gz
git-47fc52e2876ed3a54cd4b77e0b0c4875fa3317b8.tar.bz2
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>
Diffstat (limited to 'refs.c')
-rw-r--r--refs.c20
1 files changed, 11 insertions, 9 deletions
diff --git a/refs.c b/refs.c
index 5913185..4a52308 100644
--- a/refs.c
+++ b/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;
}