diff options
| author | Bryce Kwon <bryce@brycekwon.com> | |
|---|---|---|
| committer | Bryce Kwon <bryce@brycekwon.com> | |
| commit | ||
| parent | ||
| tree | ||
| download | ||
Sort an empty list without handing qsort a null
Every list sorted here is null until its first entry, and C leaves a
null base undefined even with nothing to sort. glibc declares it nonnull
and its UBSan build aborted the stats page of a repository with no
commits in the window, which the Linux matrix caught.
| -rw-r--r-- | source/cgit.c | 2 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| -rw-r--r-- | source/shared.h | 12 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| -rw-r--r-- | source/ui-refs.c | 12 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| -rw-r--r-- | source/ui-repolist.c | 2 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| -rw-r--r-- | source/ui-stats.c | 2 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
5 files changed, 21 insertions, 9 deletions
diff --git a/source/cgit.c b/source/cgit.c index 8a3d8c1..6d663fe 100644 --- a/source/cgit.c +++ b/source/cgit.c @@ -335,7 +335,7 @@ static void parse_args(int argc, const char **argv) } } if (scanned) { - qsort(cgit_repolist.repos, cgit_repolist.count, sizeof(struct cgit_repo), cmp_repos); + cgit_qsort(cgit_repolist.repos, cgit_repolist.count, sizeof(struct cgit_repo), cmp_repos); print_repolist(stdout, &cgit_repolist, 0); exit(0); } diff --git a/source/shared.h b/source/shared.h index e22eb57..2bf305d 100644 --- a/source/shared.h +++ b/source/shared.h @@ -140,4 +140,16 @@ extern int cgit_valid_rev(const char *rev); */ extern int cgit_notes_ref_usable(const char *notes_ref); +/* + * qsort for a list that may be empty. C leaves a null base undefined even + * with nothing to sort, and glibc declares it nonnull, while the lists here + * stay null until their first entry. + */ +static inline void cgit_qsort(void *base, size_t n, size_t size, + int (*cmp)(const void *, const void *)) +{ + if (n) + qsort(base, n, size, cmp); +} + #endif // CGIT_SHARED_H diff --git a/source/ui-refs.c b/source/ui-refs.c index 890a959..38a5773 100644 --- a/source/ui-refs.c +++ b/source/ui-refs.c @@ -246,9 +246,9 @@ static void print_branches_page(int pagesize) print_branch_header(); collect_branches(&list); - qsort(list.refs, list.count, sizeof(*list.refs), cmp_date); + cgit_qsort(list.refs, list.count, sizeof(*list.refs), cmp_date); if (ctx.repo->branch_sort == 0) - qsort(list.refs, list.count, sizeof(*list.refs), cmp_name); + cgit_qsort(list.refs, list.count, sizeof(*list.refs), cmp_name); page = page_bounds(pagesize, list.count); @@ -271,7 +271,7 @@ static void print_tags_page(int pagesize) collect_tags(&list); if (list.count == 0) return; - qsort(list.refs, list.count, sizeof(*list.refs), cmp_date); + cgit_qsort(list.refs, list.count, sizeof(*list.refs), cmp_date); page = page_bounds(pagesize, list.count); @@ -300,9 +300,9 @@ void cgit_print_branches(int maxcount) // The date sort covers the list, the name sort only the rows about to // be shown, so the section holds the newest branches rather than the // first ones by name. - qsort(list.refs, list.count, sizeof(*list.refs), cmp_date); + cgit_qsort(list.refs, list.count, sizeof(*list.refs), cmp_date); if (ctx.repo->branch_sort == 0) - qsort(list.refs, maxcount, sizeof(*list.refs), cmp_name); + cgit_qsort(list.refs, maxcount, sizeof(*list.refs), cmp_name); for (i = 0; i < maxcount; i++) print_branch(list.refs[i]); @@ -322,7 +322,7 @@ void cgit_print_tags(int maxcount) collect_tags(&list); if (list.count == 0) return; - qsort(list.refs, list.count, sizeof(*list.refs), cmp_date); + cgit_qsort(list.refs, list.count, sizeof(*list.refs), cmp_date); if (maxcount <= 0 || maxcount > list.count) maxcount = list.count; print_tag_header(); diff --git a/source/ui-repolist.c b/source/ui-repolist.c index 58e31ed..6df70e4 100644 --- a/source/ui-repolist.c +++ b/source/ui-repolist.c @@ -402,7 +402,7 @@ static int sort_repolist(const char *field) continue; if (column->cmp == cmp_idle || column->cmp == cmp_section) resolve_modtimes(); - qsort(cgit_repolist.repos, cgit_repolist.count, sizeof(struct cgit_repo), column->cmp); + cgit_qsort(cgit_repolist.repos, cgit_repolist.count, sizeof(struct cgit_repo), column->cmp); return 1; } return 0; diff --git a/source/ui-stats.c b/source/ui-stats.c index f200b63..a332335 100644 --- a/source/ui-stats.c +++ b/source/ui-stats.c @@ -450,7 +450,7 @@ void cgit_show_stats(void) } if (collect_stats(period, &authors)) return; - qsort(authors.items, authors.nr, sizeof(struct string_list_item), cmp_total_commits); + cgit_qsort(authors.items, authors.nr, sizeof(struct string_list_item), cmp_total_commits); top = ctx.qry.ofs; if (!top) |
