Merge branch 'jk/mailinfo-cleanup'

Code clean-up.

* jk/mailinfo-cleanup:
  mailinfo: factor out some repeated header handling
  mailinfo: be more liberal with header whitespace
  mailinfo: simplify parsing of header values
  mailinfo: treat header values as C strings
This commit is contained in:
Junio C Hamano 2020-02-17 13:22:17 -08:00
commit d880c3de23
2 changed files with 52 additions and 25 deletions

View File

@ -346,11 +346,17 @@ static const char *header[MAX_HDR_PARSED] = {
"From","Subject","Date",
};
static inline int cmp_header(const struct strbuf *line, const char *hdr)
static inline int skip_header(const struct strbuf *line, const char *hdr,
const char **outval)
{
int len = strlen(hdr);
return !strncasecmp(line->buf, hdr, len) && line->len > len &&
line->buf[len] == ':' && isspace(line->buf[len + 1]);
const char *val;
if (!skip_iprefix(line->buf, hdr, &val) ||
*val++ != ':')
return 0;
while (isspace(*val))
val++;
*outval = val;
return 1;
}
static int is_format_patch_separator(const char *line, int len)
@ -543,22 +549,36 @@ release_return:
mi->input_error = -1;
}
/*
* Returns true if "line" contains a header matching "hdr", in which case "val"
* will contain the value of the header with any RFC2047 B and Q encoding
* unwrapped, and optionally normalize the meta information to utf8.
*/
static int parse_header(const struct strbuf *line,
const char *hdr,
struct mailinfo *mi,
struct strbuf *val)
{
const char *val_str;
if (!skip_header(line, hdr, &val_str))
return 0;
strbuf_addstr(val, val_str);
decode_header(mi, val);
return 1;
}
static int check_header(struct mailinfo *mi,
const struct strbuf *line,
struct strbuf *hdr_data[], int overwrite)
{
int i, ret = 0, len;
int i, ret = 0;
struct strbuf sb = STRBUF_INIT;
/* search for the interesting parts */
for (i = 0; header[i]; i++) {
int len = strlen(header[i]);
if ((!hdr_data[i] || overwrite) && cmp_header(line, header[i])) {
/* Unwrap inline B and Q encoding, and optionally
* normalize the meta information to utf8.
*/
strbuf_add(&sb, line->buf + len + 2, line->len - len - 2);
decode_header(mi, &sb);
if ((!hdr_data[i] || overwrite) &&
parse_header(line, header[i], mi, &sb)) {
handle_header(&hdr_data[i], &sb);
ret = 1;
goto check_header_out;
@ -566,26 +586,17 @@ static int check_header(struct mailinfo *mi,
}
/* Content stuff */
if (cmp_header(line, "Content-Type")) {
len = strlen("Content-Type: ");
strbuf_add(&sb, line->buf + len, line->len - len);
decode_header(mi, &sb);
if (parse_header(line, "Content-Type", mi, &sb)) {
handle_content_type(mi, &sb);
ret = 1;
goto check_header_out;
}
if (cmp_header(line, "Content-Transfer-Encoding")) {
len = strlen("Content-Transfer-Encoding: ");
strbuf_add(&sb, line->buf + len, line->len - len);
decode_header(mi, &sb);
if (parse_header(line, "Content-Transfer-Encoding", mi, &sb)) {
handle_content_transfer_encoding(mi, &sb);
ret = 1;
goto check_header_out;
}
if (cmp_header(line, "Message-Id")) {
len = strlen("Message-Id: ");
strbuf_add(&sb, line->buf + len, line->len - len);
decode_header(mi, &sb);
if (parse_header(line, "Message-Id", mi, &sb)) {
if (mi->add_message_id)
mi->message_id = strbuf_detach(&sb, NULL);
ret = 1;
@ -606,8 +617,9 @@ static int is_inbody_header(const struct mailinfo *mi,
const struct strbuf *line)
{
int i;
const char *val;
for (i = 0; header[i]; i++)
if (!mi->s_hdr_data[i] && cmp_header(line, header[i]))
if (!mi->s_hdr_data[i] && skip_header(line, header[i], &val))
return 1;
return 0;
}

View File

@ -213,4 +213,19 @@ test_expect_failure 'mailinfo -b separated double [PATCH]' '
test z"$subj" = z"Subject: [other] message"
'
test_expect_success 'mailinfo handles unusual header whitespace' '
git mailinfo /dev/null /dev/null >actual <<-\EOF &&
From:Real Name <user@example.com>
Subject: extra spaces
EOF
cat >expect <<-\EOF &&
Author: Real Name
Email: user@example.com
Subject: extra spaces
EOF
test_cmp expect actual
'
test_done