Whilst git-shortlog(1) does not explicitly need any repository information when run without reference to one, it still parses some of its arguments with parse_revision_opt() which assumes that the hash algorithm is set. However, in c8aed5e8da (repository: stop setting SHA1 as the default object hash, 2024-05-07) we stopped setting up a default hash algorithm and instead require commands to set it up explicitly. This was done for most other commands like in ab274909d4 (builtin/diff: explicitly set hash algo when there is no repo, 2024-05-07) but was missed for builtin/shortlog, making git-shortlog(1) segfault outside of a repository when given arguments like --author that trigger a call to parse_revision_opt(). Fix this for now by explicitly setting the hash algorithm to SHA1. Also add a regression test for the segfault. Signed-off-by: Wolfgang Müller <wolf@oriole.systems> --- builtin/shortlog.c | 12 ++++++++++++ t/t4201-shortlog.sh | 5 +++++ 2 files changed, 17 insertions(+) diff --git a/builtin/shortlog.c b/builtin/shortlog.c index 3ed5c46078..0fa35202ed 100644 --- a/builtin/shortlog.c +++ b/builtin/shortlog.c @@ -387,6 +387,18 @@ int cmd_shortlog(int argc, struct rev_info rev; int nongit = !startup_info->have_repository; + /* + * NEEDSWORK: Later on we'll call parse_revision_opt which relies on + * the hash algorithm being set but since we are operating outside of a + * Git repository we cannot determine one. This is only needed because + * parse_revision_opt expects hexsz for --abbrev which is irrelevant + * for shortlog outside of a git repository. For now explicitly set + * SHA1, but ideally the parsing machinery would be split between + * git/nongit so that we do not have to do this. + */ + if (nongit && !the_hash_algo) + repo_set_hash_algo(the_repository, GIT_HASH_SHA1); + const struct option options[] = { OPT_BIT('c', "committer", &log.groups, N_("group by committer rather than author"), diff --git a/t/t4201-shortlog.sh b/t/t4201-shortlog.sh index c20c885724..ed39c67ba1 100755 --- a/t/t4201-shortlog.sh +++ b/t/t4201-shortlog.sh @@ -143,6 +143,11 @@ fuzz() test_grep "too many arguments" out ' +test_expect_success 'shortlog --author from non-git directory does not segfault' ' + git log --no-expand-tabs HEAD >log && + env GIT_DIR=non-existing git shortlog --author=author <log 2>out +' + test_expect_success 'shortlog should add newline when input line matches wraplen' ' cat >expect <<\EOF && A U Thor (2): Range-diff against v1: 1: 42516cc02d ! 1: d3047a0291 builtin/shortlog: explicitly set hash algo when there is no repo @@ Commit message a repository when given arguments like --author that trigger a call to parse_revision_opt(). - Fix this for now by explicitly setting the hash algorithm to SHA1. + Fix this for now by explicitly setting the hash algorithm to SHA1. Also + add a regression test for the segfault. Signed-off-by: Wolfgang Müller <wolf@oriole.systems> @@ builtin/shortlog.c: int cmd_shortlog(int argc, int nongit = !startup_info->have_repository; + /* -+ * Later on we'll call parse_revision_opt which relies on the hash -+ * algorithm being set but since we are operating outside of a Git -+ * repository we cannot determine one. For now default to SHA1. ++ * NEEDSWORK: Later on we'll call parse_revision_opt which relies on ++ * the hash algorithm being set but since we are operating outside of a ++ * Git repository we cannot determine one. This is only needed because ++ * parse_revision_opt expects hexsz for --abbrev which is irrelevant ++ * for shortlog outside of a git repository. For now explicitly set ++ * SHA1, but ideally the parsing machinery would be split between ++ * git/nongit so that we do not have to do this. + */ + if (nongit && !the_hash_algo) + repo_set_hash_algo(the_repository, GIT_HASH_SHA1); @@ builtin/shortlog.c: int cmd_shortlog(int argc, const struct option options[] = { OPT_BIT('c', "committer", &log.groups, N_("group by committer rather than author"), + + ## t/t4201-shortlog.sh ## +@@ t/t4201-shortlog.sh: fuzz() + test_grep "too many arguments" out + ' + ++test_expect_success 'shortlog --author from non-git directory does not segfault' ' ++ git log --no-expand-tabs HEAD >log && ++ env GIT_DIR=non-existing git shortlog --author=author <log 2>out ++' ++ + test_expect_success 'shortlog should add newline when input line matches wraplen' ' + cat >expect <<\EOF && + A U Thor (2): -- 2.47.0