blame: fix segfault on untracked files
authorThomas Gummerer <t.gummerer@gmail.com>
Sat, 27 Aug 2016 20:01:50 +0000 (21:01 +0100)
committerJunio C Hamano <gitster@pobox.com>
Mon, 29 Aug 2016 18:57:33 +0000 (11:57 -0700)
Since 3b75ee9 ("blame: allow to blame paths freshly added to the index",
2016-07-16) git blame also looks at the index to determine if there is a
file that was freshly added to the index.

cache_name_pos returns -pos - 1 in case there is no match is found, or
if the name matches, but the entry has a stage other than 0. As git
blame should work for unmerged files, it uses strcmp to determine
whether the name of the returned position matches, in which case the
file exists, but is merely unmerged, or if the file actually doesn't
exist in the index.

If the repository is empty, or if the file would lexicographically be
sorted as the last file in the repository, -cache_name_pos - 1 is
outside of the length of the active_cache array, causing git blame to
segfault. Guard against that, and die() normally to restore the old
behaviour.

Reported-by: Simon Ruderich <simon@ruderich.org>
Signed-off-by: Thomas Gummerer <t.gummerer@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
builtin/blame.c
t/t8002-blame.sh
index 12c765acfede5727b27b2afaed2eb290fd930fc6..4d52f9602eae138a9c365b8f99795a7cd6951c6b 100644 (file)
@@ -2245,7 +2245,8 @@ static void verify_working_tree_path(struct commit *work_tree, const char *path)
        pos = cache_name_pos(path, strlen(path));
        if (pos >= 0)
                ; /* path is in the index */
-       else if (!strcmp(active_cache[-1 - pos]->name, path))
+       else if (-1 - pos < active_nr &&
+                !strcmp(active_cache[-1 - pos]->name, path))
                ; /* path is in the index, unmerged */
        else
                die("no such path '%s' in HEAD", path);
index ff09aced6855dbc9eaa963571b698919d7289871..ab79de95441f4f474525b48b14313f1d04172fce 100755 (executable)
@@ -6,6 +6,11 @@ test_description='git blame'
 PROG='git blame -c'
 . "$TEST_DIRECTORY"/annotate-tests.sh
 
+test_expect_success 'blame untracked file in empty repo' '
+       >untracked &&
+       test_must_fail git blame untracked
+'
+
 PROG='git blame -c -e'
 test_expect_success 'blame --show-email' '
        check_count \