summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Gummerer <t.gummerer@gmail.com>2016-08-27 21:01:50 +0100
committerJunio C Hamano <gitster@pobox.com>2016-08-29 11:57:33 -0700
commitbc6b13a7d2300e982dd3a3aeef2f3ad4d39cf149 (patch)
treefbb0ea83fa6363d4709f022441caa4381d3d152d
parentc66b470082144471fc95e669eb398c8f320d67c4 (diff)
downloadgit-bc6b13a7d2300e982dd3a3aeef2f3ad4d39cf149.tar.gz
blame: fix segfault on untracked filesmh/blame-worktree
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>
-rw-r--r--builtin/blame.c3
-rwxr-xr-xt/t8002-blame.sh5
2 files changed, 7 insertions, 1 deletions
diff --git a/builtin/blame.c b/builtin/blame.c
index 12c765acfe..4d52f9602e 100644
--- a/builtin/blame.c
+++ b/builtin/blame.c
@@ -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);
diff --git a/t/t8002-blame.sh b/t/t8002-blame.sh
index ff09aced68..ab79de9544 100755
--- a/t/t8002-blame.sh
+++ b/t/t8002-blame.sh
@@ -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 \