Skip to content

Commit ae99e69

Browse files
authored
Merge pull request libgit2#5619 from ddevault/diffstat-segfault
diff stats: fix segfaults with new files
2 parents 298b01a + ec26b16 commit ae99e69

File tree

2 files changed

+41
-5
lines changed

2 files changed

+41
-5
lines changed

src/diff_stats.c

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ static int diff_file_stats_full_to_buf(
5353
const git_diff_stats *stats,
5454
size_t width)
5555
{
56-
const char *old_path = NULL, *new_path = NULL;
56+
const char *old_path = NULL, *new_path = NULL, *adddel_path = NULL;
5757
size_t padding;
5858
git_object_size_t old_size, new_size;
5959

@@ -62,7 +62,7 @@ static int diff_file_stats_full_to_buf(
6262
old_size = delta->old_file.size;
6363
new_size = delta->new_file.size;
6464

65-
if (strcmp(old_path, new_path) != 0) {
65+
if (old_path && new_path && strcmp(old_path, new_path) != 0) {
6666
size_t common_dirlen;
6767
int error;
6868

@@ -82,10 +82,11 @@ static int diff_file_stats_full_to_buf(
8282
if (error < 0)
8383
goto on_error;
8484
} else {
85-
if (git_buf_printf(out, " %s", old_path) < 0)
85+
adddel_path = new_path ? new_path : old_path;
86+
if (git_buf_printf(out, " %s", adddel_path) < 0)
8687
goto on_error;
8788

88-
padding = stats->max_name - strlen(old_path);
89+
padding = stats->max_name - strlen(adddel_path);
8990

9091
if (stats->renames > 0)
9192
padding += strlen(DIFF_RENAME_FILE_SEPARATOR);
@@ -211,7 +212,7 @@ int git_diff_get_stats(
211212

212213
/* TODO ugh */
213214
namelen = strlen(delta->new_file.path);
214-
if (strcmp(delta->old_file.path, delta->new_file.path) != 0) {
215+
if (delta->old_file.path && strcmp(delta->old_file.path, delta->new_file.path) != 0) {
215216
namelen += strlen(delta->old_file.path);
216217
stats->renames++;
217218
}

tests/diff/stats.c

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -343,3 +343,38 @@ void test_diff_stats__mode_change(void)
343343
cl_assert_equal_s(stat, git_buf_cstr(&buf));
344344
git_buf_dispose(&buf);
345345
}
346+
347+
void test_diff_stats__new_file(void)
348+
{
349+
git_diff *diff;
350+
git_buf buf = GIT_BUF_INIT;
351+
352+
const char *input =
353+
"---\n"
354+
" Gurjeet Singh | 1 +\n"
355+
" 1 file changed, 1 insertion(+)\n"
356+
" create mode 100644 Gurjeet Singh\n"
357+
"\n"
358+
"diff --git a/Gurjeet Singh b/Gurjeet Singh\n"
359+
"new file mode 100644\n"
360+
"index 0000000..6d0ecfd\n"
361+
"--- /dev/null\n"
362+
"+++ b/Gurjeet Singh \n"
363+
"@@ -0,0 +1 @@\n"
364+
"+I'm about to try git send-email\n"
365+
"-- \n"
366+
"2.21.0\n";
367+
368+
const char *stat =
369+
" Gurjeet Singh | 1 +\n"
370+
" 1 file changed, 1 insertion(+)\n"
371+
" create mode 100644 Gurjeet Singh\n";
372+
373+
cl_git_pass(git_diff_from_buffer(&diff, input, strlen(input)));
374+
cl_git_pass(git_diff_get_stats(&_stats, diff));
375+
cl_git_pass(git_diff_stats_to_buf(&buf, _stats, GIT_DIFF_STATS_FULL | GIT_DIFF_STATS_INCLUDE_SUMMARY, 0));
376+
cl_assert_equal_s(stat, git_buf_cstr(&buf));
377+
378+
git_buf_dispose(&buf);
379+
git_diff_free(diff);
380+
}

0 commit comments

Comments
 (0)