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 --- builtin/checkout.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'builtin/checkout.c') diff --git a/builtin/checkout.c b/builtin/checkout.c index beeaee4113..c6919f1687 100644 --- a/builtin/checkout.c +++ b/builtin/checkout.c @@ -699,7 +699,9 @@ static int switch_branches(struct checkout_opts *opts, struct branch_info *new) unsigned char rev[20]; int flag; memset(&old, 0, sizeof(old)); - old.path = xstrdup(resolve_ref("HEAD", rev, 0, &flag)); + old.path = resolve_ref("HEAD", rev, 0, &flag); + if (old.path) + old.path = xstrdup(old.path); old.commit = lookup_commit_reference_gently(rev, 1); if (!(flag & REF_ISSYMREF)) { free((char *)old.path); -- cgit v1.2.1