Copy resolve_ref() return value for longer use
authorNguyễn Thái Ngọc Duy <pclouds@gmail.com>
Sun, 13 Nov 2011 10:22:15 +0000 (17:22 +0700)
committerJunio C Hamano <gitster@pobox.com>
Tue, 6 Dec 2011 00:21:06 +0000 (16:21 -0800)
commitd5a35c114ab6b4337a1c7598bf75c331d94ee092
tree675d14129b5e8e7b06210e37e1b8dbd147ab9e09
parentc6893323917cbf4cb66c29ba2ac03014a44f0f0c
Copy resolve_ref() return value for longer use

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 <wwwjfy@gmail.com> 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 <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
builtin/branch.c
builtin/checkout.c
builtin/commit.c
builtin/fmt-merge-msg.c
builtin/merge.c
builtin/notes.c
builtin/receive-pack.c
reflog-walk.c