From d5a35c114ab6b4337a1c7598bf75c331d94ee092 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nguy=E1=BB=85n=20Th=C3=A1i=20Ng=E1=BB=8Dc=20Duy?= Date: Sun, 13 Nov 2011 17:22:15 +0700 Subject: Copy resolve_ref() return value for longer use MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit resolve_ref() may return a pointer to a static buffer. Callers that use this value longer than a couple of statements should copy the value to avoid some hidden resolve_ref() call that may change the static buffer's value. The bug found by Tony Wang in builtin/merge.c demonstrates this. The first call is in cmd_merge() branch = resolve_ref("HEAD", head_sha1, 0, &flag); Then deep in lookup_commit_or_die() a few lines after, resolve_ref() may be called again and destroy "branch". lookup_commit_or_die lookup_commit_reference lookup_commit_reference_gently parse_object lookup_replace_object do_lookup_replace_object prepare_replace_object for_each_replace_ref do_for_each_ref get_loose_refs get_ref_dir get_ref_dir resolve_ref All call sites are checked and made sure that xstrdup() is called if the value should be saved. Signed-off-by: Nguyễn Thái Ngọc Duy Signed-off-by: Junio C Hamano --- reflog-walk.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'reflog-walk.c') diff --git a/reflog-walk.c b/reflog-walk.c index 5d81d39a52..da71a85851 100644 --- a/reflog-walk.c +++ b/reflog-walk.c @@ -51,8 +51,11 @@ static struct complete_reflogs *read_complete_reflog(const char *ref) if (reflogs->nr == 0) { unsigned char sha1[20]; const char *name = resolve_ref(ref, sha1, 1, NULL); - if (name) + if (name) { + name = xstrdup(name); for_each_reflog_ent(name, read_one_reflog, reflogs); + free((char *)name); + } } if (reflogs->nr == 0) { int len = strlen(ref); -- cgit v1.2.3