Implement a function based on `mailinfo.c:is_mail`. Signed-off-by: Kristoffer Haugsbakk <code@xxxxxxxxxxxxxxx> --- Notes (series): Isolating this for review as its own commit so that I can point out the provenance. May well be squashed into the main patch eventually. builtin/log.c | 33 +++++++++++++++++++++++++++++++++ t/t4014-format-patch.sh | 13 +++++++++++++ 2 files changed, 46 insertions(+) diff --git a/builtin/log.c b/builtin/log.c index eecbcdf1d6d..27e1a66dd03 100644 --- a/builtin/log.c +++ b/builtin/log.c @@ -1872,6 +1872,35 @@ static void infer_range_diff_ranges(struct strbuf *r1, } } +static int is_mail(struct strbuf *sb) +{ + const char *header_regex = "^[!-9;-~]+:"; + regex_t regex; + int ret = 1, i; + struct string_list list = STRING_LIST_INIT_DUP; + + if (regcomp(®ex, header_regex, REG_NOSUB | REG_EXTENDED)) + die("invalid pattern: %s", header_regex); + string_list_split(&list, sb->buf, '\n', -1); + for (i = 0; i < list.nr; i++) { + /* End of header */ + if (!*list.items[i].string && i == (list.nr - 1)) + break; + /* Ignore indented folded lines */ + if (*list.items[i].string == '\t' || + *list.items[i].string == ' ') + continue; + /* It's a header if it matches header_regex */ + if (regexec(®ex, list.items[i].string, 0, NULL, 0)) { + ret = 0; + break; + } + } + string_list_clear(&list, 1); + regfree(®ex); + return ret; +} + /* Returns an owned pointer */ static char *header_cmd_output(struct rev_info *rev, const struct commit *cmit) { @@ -1898,6 +1927,10 @@ static char *header_cmd_output(struct rev_info *rev, const struct commit *cmit) die(_("header-cmd %s: failed with exit code %d"), header_cmd, res); } + if (!is_mail(&output)) + die(_("header-cmd %s: returned output which was " + "not recognized as valid RFC 2822 headers"), + header_cmd); return strbuf_detach(&output, NULL); } diff --git a/t/t4014-format-patch.sh b/t/t4014-format-patch.sh index dfda21d4b2b..98e0eb706e6 100755 --- a/t/t4014-format-patch.sh +++ b/t/t4014-format-patch.sh @@ -258,6 +258,19 @@ test_expect_success '--header-cmd with no output works' ' git format-patch --header-cmd=./cmd --stdout main..side ' +test_expect_success '--header-cmd without headers-like output fails' ' + write_script cmd <<-\EOF && + printf "X-S: $GIT_FP_HEADER_CMD_HASH\n" + printf "\n" + printf "X-C: $GIT_FP_HEADER_CMD_COUNT\n" + EOF + cat > expect <<-\EOF && + fatal: header-cmd ./cmd: returned output which was not recognized as valid RFC 2822 headers + EOF + test_must_fail git format-patch --header-cmd=./cmd --stdout main..side >actual 2>&1 && + test_cmp expect actual +' + test_expect_success '--header-cmd reports failed command' ' write_script cmd <<-\EOF && exit 1 -- 2.44.0.169.gd259cac85a8