From 62d59467615c19869c6a504bcf76d1f655a55552 Mon Sep 17 00:00:00 2001 From: lhchavez Date: Sun, 8 Mar 2020 02:13:11 +0000 Subject: Fix segfault when calling git_blame_buffer() This change makes sure that the hunk is not null before trying to dereference it. This avoids segfaults, especially when blaming against a modified buffer (i.e. the index). Fixes: #5443 --- src/blame.c | 2 +- tests/blame/buffer.c | 26 +++++++++++++++++++++ .../83/6bc00b06cb60eb0f629e237ad2b58adb2cfc7e | 3 +++ .../a8/ba8436b5d8ccbdfd5be597c194e7bb8e0a092f | 1 + .../f9/264f7fbd31ae7a18b7931ed8946fb0aebb0af3 | Bin 0 -> 28 bytes tests/resources/blametest.git/refs/heads/master | 2 +- 6 files changed, 32 insertions(+), 2 deletions(-) create mode 100644 tests/resources/blametest.git/objects/83/6bc00b06cb60eb0f629e237ad2b58adb2cfc7e create mode 100644 tests/resources/blametest.git/objects/a8/ba8436b5d8ccbdfd5be597c194e7bb8e0a092f create mode 100644 tests/resources/blametest.git/objects/f9/264f7fbd31ae7a18b7931ed8946fb0aebb0af3 diff --git a/src/blame.c b/src/blame.c index 404f1f643..23c21027a 100644 --- a/src/blame.c +++ b/src/blame.c @@ -415,7 +415,7 @@ on_error: static bool hunk_is_bufferblame(git_blame_hunk *hunk) { - return git_oid_is_zero(&hunk->final_commit_id); + return hunk && git_oid_is_zero(&hunk->final_commit_id); } static int buffer_hunk_cb( diff --git a/tests/blame/buffer.c b/tests/blame/buffer.c index 340b1dced..06d5042dd 100644 --- a/tests/blame/buffer.c +++ b/tests/blame/buffer.c @@ -17,6 +17,32 @@ void test_blame_buffer__cleanup(void) git_repository_free(g_repo); } +void test_blame_buffer__index(void) +{ + const git_blame_hunk *hunk; + const char *buffer = "Hello\nWorld!"; + + /* + * We need to open a different file from the ones used in other tests. Close + * the one opened in test_blame_buffer__initialize() to avoid a leak. + */ + git_blame_free(g_fileblame); + g_fileblame = NULL; + cl_git_pass(git_blame_file(&g_fileblame, g_repo, "file.txt", NULL)); + + cl_git_pass(git_blame_buffer(&g_bufferblame, g_fileblame, buffer, strlen(buffer))); + cl_assert_equal_i(2, git_blame_get_hunk_count(g_bufferblame)); + + check_blame_hunk_index(g_repo, g_bufferblame, 0, 1, 1, 0, "836bc00b", "file.txt"); + hunk = git_blame_get_hunk_byline(g_bufferblame, 1); + cl_assert(hunk); + cl_assert_equal_s("lhchavez", hunk->final_signature->name); + check_blame_hunk_index(g_repo, g_bufferblame, 1, 2, 1, 0, "00000000", "file.txt"); + hunk = git_blame_get_hunk_byline(g_bufferblame, 2); + cl_assert(hunk); + cl_assert(hunk->final_signature == NULL); +} + void test_blame_buffer__added_line(void) { const git_blame_hunk *hunk; diff --git a/tests/resources/blametest.git/objects/83/6bc00b06cb60eb0f629e237ad2b58adb2cfc7e b/tests/resources/blametest.git/objects/83/6bc00b06cb60eb0f629e237ad2b58adb2cfc7e new file mode 100644 index 000000000..71f9c980e --- /dev/null +++ b/tests/resources/blametest.git/objects/83/6bc00b06cb60eb0f629e237ad2b58adb2cfc7e @@ -0,0 +1,3 @@ +xK +1D]B$OD{{: OգAyu" RAˆ41f/]UϲȣX +MȖ,sFc8S[}⩼壏78pO.%fZua\uJF \ No newline at end of file diff --git a/tests/resources/blametest.git/objects/a8/ba8436b5d8ccbdfd5be597c194e7bb8e0a092f b/tests/resources/blametest.git/objects/a8/ba8436b5d8ccbdfd5be597c194e7bb8e0a092f new file mode 100644 index 000000000..0bab0ef53 --- /dev/null +++ b/tests/resources/blametest.git/objects/a8/ba8436b5d8ccbdfd5be597c194e7bb8e0a092f @@ -0,0 +1 @@ +x+)JMU04`040031QH+(aٵJ5Ѕ'3P%0 }_ՉΓE{4٩r -3'槚^uU'ݘanP55?p9_$*\9 \ No newline at end of file diff --git a/tests/resources/blametest.git/objects/f9/264f7fbd31ae7a18b7931ed8946fb0aebb0af3 b/tests/resources/blametest.git/objects/f9/264f7fbd31ae7a18b7931ed8946fb0aebb0af3 new file mode 100644 index 000000000..942a7eedc Binary files /dev/null and b/tests/resources/blametest.git/objects/f9/264f7fbd31ae7a18b7931ed8946fb0aebb0af3 differ diff --git a/tests/resources/blametest.git/refs/heads/master b/tests/resources/blametest.git/refs/heads/master index d1bc4ca6b..994877a20 100644 --- a/tests/resources/blametest.git/refs/heads/master +++ b/tests/resources/blametest.git/refs/heads/master @@ -1 +1 @@ -6653ff42313eb5c82806f145391b18a9699800c7 +836bc00b06cb60eb0f629e237ad2b58adb2cfc7e -- cgit v1.2.1