1
0
Fork 0
mirror of https://github.com/git/git.git synced 2024-06-18 18:59:38 +02:00

mailinfo: simplify parsing of header values

Our code to parse header values first checks to see if a line starts
with a header, and then manually skips past the matched string to find
the value. We can do this all in one step by modeling after
skip_prefix(), which returns a pointer into the string after the
parsing.

This lets us remove some repeated strings, and will also enable us to
parse more flexibly in a future patch.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Jeff King 2020-02-11 12:19:23 -05:00 committed by Junio C Hamano
parent b6537d83ee
commit f447d0293e

View File

@ -346,11 +346,16 @@ static const char *header[MAX_HDR_PARSED] = {
"From","Subject","Date", "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); const char *val;
return !strncasecmp(line->buf, hdr, len) && line->len > len && if (!skip_iprefix(line->buf, hdr, &val) ||
line->buf[len] == ':' && isspace(line->buf[len + 1]); *val++ != ':' ||
!isspace(*val++))
return 0;
*outval = val;
return 1;
} }
static int is_format_patch_separator(const char *line, int len) static int is_format_patch_separator(const char *line, int len)
@ -547,17 +552,18 @@ static int check_header(struct mailinfo *mi,
const struct strbuf *line, const struct strbuf *line,
struct strbuf *hdr_data[], int overwrite) struct strbuf *hdr_data[], int overwrite)
{ {
int i, ret = 0, len; int i, ret = 0;
struct strbuf sb = STRBUF_INIT; struct strbuf sb = STRBUF_INIT;
const char *val;
/* search for the interesting parts */ /* search for the interesting parts */
for (i = 0; header[i]; i++) { for (i = 0; header[i]; i++) {
int len = strlen(header[i]); if ((!hdr_data[i] || overwrite) &&
if ((!hdr_data[i] || overwrite) && cmp_header(line, header[i])) { skip_header(line, header[i], &val)) {
/* Unwrap inline B and Q encoding, and optionally /* Unwrap inline B and Q encoding, and optionally
* normalize the meta information to utf8. * normalize the meta information to utf8.
*/ */
strbuf_addstr(&sb, line->buf + len + 2); strbuf_addstr(&sb, val);
decode_header(mi, &sb); decode_header(mi, &sb);
handle_header(&hdr_data[i], &sb); handle_header(&hdr_data[i], &sb);
ret = 1; ret = 1;
@ -566,25 +572,22 @@ static int check_header(struct mailinfo *mi,
} }
/* Content stuff */ /* Content stuff */
if (cmp_header(line, "Content-Type")) { if (skip_header(line, "Content-Type", &val)) {
len = strlen("Content-Type: "); strbuf_addstr(&sb, val);
strbuf_addstr(&sb, line->buf + len);
decode_header(mi, &sb); decode_header(mi, &sb);
handle_content_type(mi, &sb); handle_content_type(mi, &sb);
ret = 1; ret = 1;
goto check_header_out; goto check_header_out;
} }
if (cmp_header(line, "Content-Transfer-Encoding")) { if (skip_header(line, "Content-Transfer-Encoding", &val)) {
len = strlen("Content-Transfer-Encoding: "); strbuf_addstr(&sb, val);
strbuf_addstr(&sb, line->buf + len);
decode_header(mi, &sb); decode_header(mi, &sb);
handle_content_transfer_encoding(mi, &sb); handle_content_transfer_encoding(mi, &sb);
ret = 1; ret = 1;
goto check_header_out; goto check_header_out;
} }
if (cmp_header(line, "Message-Id")) { if (skip_header(line, "Message-Id", &val)) {
len = strlen("Message-Id: "); strbuf_addstr(&sb, val);
strbuf_addstr(&sb, line->buf + len);
decode_header(mi, &sb); decode_header(mi, &sb);
if (mi->add_message_id) if (mi->add_message_id)
mi->message_id = strbuf_detach(&sb, NULL); mi->message_id = strbuf_detach(&sb, NULL);
@ -606,8 +609,9 @@ static int is_inbody_header(const struct mailinfo *mi,
const struct strbuf *line) const struct strbuf *line)
{ {
int i; int i;
const char *val;
for (i = 0; header[i]; i++) 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 1;
return 0; return 0;
} }