mirror of
https://git.proxmox.com/git/libgit2
synced 2025-05-06 07:47:18 +00:00
Merge pull request #1701 from yorah/fix/gh-1698
Fix segfault in git_status_foreach_ext()
This commit is contained in:
commit
4ae29053d5
@ -1273,7 +1273,7 @@ int git_diff__paired_foreach(
|
||||
git_vector_sort(&idx2wd->deltas);
|
||||
}
|
||||
}
|
||||
else if (head2idx->opts.flags & GIT_DIFF_DELTAS_ARE_ICASE)
|
||||
else if (head2idx != NULL && head2idx->opts.flags & GIT_DIFF_DELTAS_ARE_ICASE)
|
||||
strcomp = git__strcasecmp;
|
||||
|
||||
for (i = 0, j = 0; i < i_max || j < j_max; ) {
|
||||
|
12
src/status.c
12
src/status.c
@ -257,6 +257,7 @@ int git_status_list_new(
|
||||
opts ? opts->show : GIT_STATUS_SHOW_INDEX_AND_WORKDIR;
|
||||
int error = 0;
|
||||
unsigned int flags = opts ? opts->flags : GIT_STATUS_OPT_DEFAULTS;
|
||||
git_diff_list *head2idx = NULL;
|
||||
|
||||
assert(show <= GIT_STATUS_SHOW_INDEX_THEN_WORKDIR);
|
||||
|
||||
@ -307,8 +308,10 @@ int git_status_list_new(
|
||||
&status->head2idx, repo, head, NULL, &diffopt)) < 0)
|
||||
goto done;
|
||||
|
||||
head2idx = status->head2idx;
|
||||
|
||||
if ((flags & GIT_STATUS_OPT_RENAMES_HEAD_TO_INDEX) != 0 &&
|
||||
(error = git_diff_find_similar(status->head2idx, NULL)) < 0)
|
||||
(error = git_diff_find_similar(head2idx, NULL)) < 0)
|
||||
goto done;
|
||||
}
|
||||
|
||||
@ -324,15 +327,14 @@ int git_status_list_new(
|
||||
|
||||
if (show == GIT_STATUS_SHOW_INDEX_THEN_WORKDIR) {
|
||||
if ((error = git_diff__paired_foreach(
|
||||
status->head2idx, NULL, status_collect, status)) < 0)
|
||||
head2idx, NULL, status_collect, status)) < 0)
|
||||
goto done;
|
||||
|
||||
git_diff_list_free(status->head2idx);
|
||||
status->head2idx = NULL;
|
||||
head2idx = NULL;
|
||||
}
|
||||
|
||||
if ((error = git_diff__paired_foreach(
|
||||
status->head2idx, status->idx2wd, status_collect, status)) < 0)
|
||||
head2idx, status->idx2wd, status_collect, status)) < 0)
|
||||
goto done;
|
||||
|
||||
if (flags & GIT_STATUS_OPT_SORT_CASE_SENSITIVELY)
|
||||
|
@ -250,3 +250,130 @@ static const unsigned int entry_statuses4[] = {
|
||||
};
|
||||
|
||||
static const int entry_count4 = 23;
|
||||
|
||||
|
||||
/* entries for a copy of tests/resources/status with options
|
||||
* passed to the status call in order to only get the differences
|
||||
* between the HEAD and the index (changes to be committed)
|
||||
*/
|
||||
|
||||
static const char *entry_paths5[] = {
|
||||
"staged_changes",
|
||||
"staged_changes_file_deleted",
|
||||
"staged_changes_modified_file",
|
||||
"staged_delete_file_deleted",
|
||||
"staged_delete_modified_file",
|
||||
"staged_new_file",
|
||||
"staged_new_file_deleted_file",
|
||||
"staged_new_file_modified_file",
|
||||
};
|
||||
|
||||
static const unsigned int entry_statuses5[] = {
|
||||
GIT_STATUS_INDEX_MODIFIED,
|
||||
GIT_STATUS_INDEX_MODIFIED,
|
||||
GIT_STATUS_INDEX_MODIFIED,
|
||||
GIT_STATUS_INDEX_DELETED,
|
||||
GIT_STATUS_INDEX_DELETED,
|
||||
GIT_STATUS_INDEX_NEW,
|
||||
GIT_STATUS_INDEX_NEW,
|
||||
GIT_STATUS_INDEX_NEW,
|
||||
};
|
||||
|
||||
static const int entry_count5 = 8;
|
||||
|
||||
|
||||
/* entries for a copy of tests/resources/status with options
|
||||
* passed to the status call in order to only get the differences
|
||||
* between the workdir and the index (changes not staged, untracked files)
|
||||
*/
|
||||
|
||||
static const char *entry_paths6[] = {
|
||||
"file_deleted",
|
||||
"ignored_file",
|
||||
"modified_file",
|
||||
"new_file",
|
||||
"staged_changes_file_deleted",
|
||||
"staged_changes_modified_file",
|
||||
"staged_delete_modified_file",
|
||||
"staged_new_file_deleted_file",
|
||||
"staged_new_file_modified_file",
|
||||
"subdir/deleted_file",
|
||||
"subdir/modified_file",
|
||||
"subdir/new_file",
|
||||
"\xe8\xbf\x99",
|
||||
};
|
||||
|
||||
static const unsigned int entry_statuses6[] = {
|
||||
GIT_STATUS_WT_DELETED,
|
||||
GIT_STATUS_IGNORED,
|
||||
GIT_STATUS_WT_MODIFIED,
|
||||
GIT_STATUS_WT_NEW,
|
||||
GIT_STATUS_WT_DELETED,
|
||||
GIT_STATUS_WT_MODIFIED,
|
||||
GIT_STATUS_WT_NEW,
|
||||
GIT_STATUS_WT_DELETED,
|
||||
GIT_STATUS_WT_MODIFIED,
|
||||
GIT_STATUS_WT_DELETED,
|
||||
GIT_STATUS_WT_MODIFIED,
|
||||
GIT_STATUS_WT_NEW,
|
||||
GIT_STATUS_WT_NEW,
|
||||
};
|
||||
|
||||
static const int entry_count6 = 13;
|
||||
|
||||
|
||||
/* entries for a copy of tests/resources/status with options
|
||||
* passed to the status call in order to get the differences
|
||||
* between the HEAD and the index and then between the workdir
|
||||
* and the index.
|
||||
*/
|
||||
|
||||
static const char *entry_paths7[] = {
|
||||
"staged_changes",
|
||||
"staged_changes_file_deleted",
|
||||
"staged_changes_modified_file",
|
||||
"staged_delete_file_deleted",
|
||||
"staged_delete_modified_file",
|
||||
"staged_new_file",
|
||||
"staged_new_file_deleted_file",
|
||||
"staged_new_file_modified_file",
|
||||
"file_deleted",
|
||||
"ignored_file",
|
||||
"modified_file",
|
||||
"new_file",
|
||||
"staged_changes_file_deleted",
|
||||
"staged_changes_modified_file",
|
||||
"staged_delete_modified_file",
|
||||
"staged_new_file_deleted_file",
|
||||
"staged_new_file_modified_file",
|
||||
"subdir/deleted_file",
|
||||
"subdir/modified_file",
|
||||
"subdir/new_file",
|
||||
"\xe8\xbf\x99",
|
||||
};
|
||||
|
||||
static const unsigned int entry_statuses7[] = {
|
||||
GIT_STATUS_INDEX_MODIFIED,
|
||||
GIT_STATUS_INDEX_MODIFIED,
|
||||
GIT_STATUS_INDEX_MODIFIED,
|
||||
GIT_STATUS_INDEX_DELETED,
|
||||
GIT_STATUS_INDEX_DELETED,
|
||||
GIT_STATUS_INDEX_NEW,
|
||||
GIT_STATUS_INDEX_NEW,
|
||||
GIT_STATUS_INDEX_NEW,
|
||||
GIT_STATUS_WT_DELETED,
|
||||
GIT_STATUS_IGNORED,
|
||||
GIT_STATUS_WT_MODIFIED,
|
||||
GIT_STATUS_WT_NEW,
|
||||
GIT_STATUS_WT_DELETED,
|
||||
GIT_STATUS_WT_MODIFIED,
|
||||
GIT_STATUS_WT_NEW,
|
||||
GIT_STATUS_WT_DELETED,
|
||||
GIT_STATUS_WT_MODIFIED,
|
||||
GIT_STATUS_WT_DELETED,
|
||||
GIT_STATUS_WT_MODIFIED,
|
||||
GIT_STATUS_WT_NEW,
|
||||
GIT_STATUS_WT_NEW,
|
||||
};
|
||||
|
||||
static const int entry_count7 = 21;
|
||||
|
@ -40,6 +40,54 @@ void test_status_worktree__whole_repository(void)
|
||||
cl_assert_equal_i(0, counts.wrong_sorted_path);
|
||||
}
|
||||
|
||||
void assert_show(const int entry_counts, const char *entry_paths[],
|
||||
const unsigned int entry_statuses[], git_status_show_t show)
|
||||
{
|
||||
status_entry_counts counts;
|
||||
git_repository *repo = cl_git_sandbox_init("status");
|
||||
git_status_options opts = GIT_STATUS_OPTIONS_INIT;
|
||||
|
||||
memset(&counts, 0x0, sizeof(status_entry_counts));
|
||||
counts.expected_entry_count = entry_counts;
|
||||
counts.expected_paths = entry_paths;
|
||||
counts.expected_statuses = entry_statuses;
|
||||
|
||||
opts.flags = GIT_STATUS_OPT_DEFAULTS;
|
||||
opts.show = show;
|
||||
|
||||
cl_git_pass(
|
||||
git_status_foreach_ext(repo, &opts, cb_status__normal, &counts)
|
||||
);
|
||||
|
||||
cl_assert_equal_i(counts.expected_entry_count, counts.entry_count);
|
||||
cl_assert_equal_i(0, counts.wrong_status_flags_count);
|
||||
cl_assert_equal_i(0, counts.wrong_sorted_path);
|
||||
}
|
||||
|
||||
void test_status_worktree__show_index_and_workdir(void)
|
||||
{
|
||||
assert_show(entry_count0, entry_paths0, entry_statuses0,
|
||||
GIT_STATUS_SHOW_INDEX_AND_WORKDIR);
|
||||
}
|
||||
|
||||
void test_status_worktree__show_index_only(void)
|
||||
{
|
||||
assert_show(entry_count5, entry_paths5, entry_statuses5,
|
||||
GIT_STATUS_SHOW_INDEX_ONLY);
|
||||
}
|
||||
|
||||
void test_status_worktree__show_workdir_only(void)
|
||||
{
|
||||
assert_show(entry_count6, entry_paths6, entry_statuses6,
|
||||
GIT_STATUS_SHOW_WORKDIR_ONLY);
|
||||
}
|
||||
|
||||
void test_status_worktree__show_index_then_workdir_only(void)
|
||||
{
|
||||
assert_show(entry_count7, entry_paths7, entry_statuses7,
|
||||
GIT_STATUS_SHOW_INDEX_THEN_WORKDIR);
|
||||
}
|
||||
|
||||
/* this test is equivalent to t18-status.c:statuscb1 */
|
||||
void test_status_worktree__empty_repository(void)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user