From f4609b896fac842433bd495c166d5987852a6a73 Mon Sep 17 00:00:00 2001 From: Vincent Ambo Date: Sat, 21 Nov 2020 19:20:35 +0100 Subject: merge(3p/git): Merge git subtree at v2.29.2 This also bumps the stable nixpkgs to 20.09 as of 2020-11-21, because there is some breakage in the git build related to the netrc credentials helper which someone has taken care of in nixpkgs. The stable channel is not used for anything other than git, so this should be fine. Change-Id: I3575a19dab09e1e9556cf8231d717de9890484fb --- third_party/git/mailinfo.c | 79 ++++++++++++++++++++++++++++------------------ 1 file changed, 48 insertions(+), 31 deletions(-) (limited to 'third_party/git/mailinfo.c') diff --git a/third_party/git/mailinfo.c b/third_party/git/mailinfo.c index b395adbdf2a4..5681d9130db6 100644 --- a/third_party/git/mailinfo.c +++ b/third_party/git/mailinfo.c @@ -19,8 +19,7 @@ static void cleanup_space(struct strbuf *sb) static void get_sane_name(struct strbuf *out, struct strbuf *name, struct strbuf *email) { struct strbuf *src = name; - if (name->len < 3 || 60 < name->len || strchr(name->buf, '@') || - strchr(name->buf, '<') || strchr(name->buf, '>')) + if (name->len < 3 || 60 < name->len || strpbrk(name->buf, "@<>")) src = email; else if (name == out) return; @@ -254,7 +253,7 @@ static void handle_content_type(struct mailinfo *mi, struct strbuf *line) mi->delsp = has_attr_value(line->buf, "delsp=", "yes"); if (slurp_attr(line->buf, "boundary=", boundary)) { - strbuf_insert(boundary, 0, "--", 2); + strbuf_insertstr(boundary, 0, "--"); if (++mi->content_top >= &mi->content[MAX_BOUNDARIES]) { error("Too many boundaries to handle"); mi->input_error = -1; @@ -346,11 +345,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) @@ -442,19 +447,21 @@ static int convert_to_utf8(struct mailinfo *mi, struct strbuf *line, const char *charset) { char *out; + size_t out_len; if (!mi->metainfo_charset || !charset || !*charset) return 0; if (same_encoding(mi->metainfo_charset, charset)) return 0; - out = reencode_string(line->buf, mi->metainfo_charset, charset); + out = reencode_string_len(line->buf, line->len, + mi->metainfo_charset, charset, &out_len); if (!out) { mi->input_error = -1; return error("cannot convert from %s to %s", charset, mi->metainfo_charset); } - strbuf_attach(line, out, strlen(out), strlen(out)); + strbuf_attach(line, out, out_len, out_len); return 0; } @@ -543,22 +550,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,27 +587,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); - strbuf_insert(&sb, 0, "Content-Type: ", len); + 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; @@ -607,8 +618,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; } @@ -1126,6 +1138,11 @@ static void handle_info(struct mailinfo *mi) else continue; + if (memchr(hdr->buf, '\0', hdr->len)) { + error("a NUL byte in '%s' is not allowed.", header[i]); + mi->input_error = -1; + } + if (!strcmp(header[i], "Subject")) { if (!mi->keep_subject) { cleanup_subject(mi, hdr); -- cgit 1.4.1