about summary refs log tree commit diff
path: root/third_party/git/mailinfo.c
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/git/mailinfo.c')
-rw-r--r--third_party/git/mailinfo.c68
1 files changed, 29 insertions, 39 deletions
diff --git a/third_party/git/mailinfo.c b/third_party/git/mailinfo.c
index 742fa376ab01..b395adbdf2a4 100644
--- a/third_party/git/mailinfo.c
+++ b/third_party/git/mailinfo.c
@@ -19,7 +19,8 @@ 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 || strpbrk(name->buf, "@<>"))
+	if (name->len < 3 || 60 < name->len || strchr(name->buf, '@') ||
+		strchr(name->buf, '<') || strchr(name->buf, '>'))
 		src = email;
 	else if (name == out)
 		return;
@@ -253,7 +254,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_insertstr(boundary, 0, "--");
+		strbuf_insert(boundary, 0, "--", 2);
 		if (++mi->content_top >= &mi->content[MAX_BOUNDARIES]) {
 			error("Too many boundaries to handle");
 			mi->input_error = -1;
@@ -345,17 +346,11 @@ static const char *header[MAX_HDR_PARSED] = {
 	"From","Subject","Date",
 };
 
-static inline int skip_header(const struct strbuf *line, const char *hdr,
-			      const char **outval)
+static inline int cmp_header(const struct strbuf *line, const char *hdr)
 {
-	const char *val;
-	if (!skip_iprefix(line->buf, hdr, &val) ||
-	    *val++ != ':')
-		return 0;
-	while (isspace(*val))
-		val++;
-	*outval = val;
-	return 1;
+	int len = strlen(hdr);
+	return !strncasecmp(line->buf, hdr, len) && line->len > len &&
+			line->buf[len] == ':' && isspace(line->buf[len + 1]);
 }
 
 static int is_format_patch_separator(const char *line, int len)
@@ -548,36 +543,22 @@ 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;
+	int i, ret = 0, len;
 	struct strbuf sb = STRBUF_INIT;
 
 	/* search for the interesting parts */
 	for (i = 0; header[i]; i++) {
-		if ((!hdr_data[i] || overwrite) &&
-		    parse_header(line, header[i], mi, &sb)) {
+		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);
 			handle_header(&hdr_data[i], &sb);
 			ret = 1;
 			goto check_header_out;
@@ -585,17 +566,27 @@ static int check_header(struct mailinfo *mi,
 	}
 
 	/* Content stuff */
-	if (parse_header(line, "Content-Type", mi, &sb)) {
+	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);
 		handle_content_type(mi, &sb);
 		ret = 1;
 		goto check_header_out;
 	}
-	if (parse_header(line, "Content-Transfer-Encoding", mi, &sb)) {
+	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);
 		handle_content_transfer_encoding(mi, &sb);
 		ret = 1;
 		goto check_header_out;
 	}
-	if (parse_header(line, "Message-Id", mi, &sb)) {
+	if (cmp_header(line, "Message-Id")) {
+		len = strlen("Message-Id: ");
+		strbuf_add(&sb, line->buf + len, line->len - len);
+		decode_header(mi, &sb);
 		if (mi->add_message_id)
 			mi->message_id = strbuf_detach(&sb, NULL);
 		ret = 1;
@@ -616,9 +607,8 @@ 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] && skip_header(line, header[i], &val))
+		if (!mi->s_hdr_data[i] && cmp_header(line, header[i]))
 			return 1;
 	return 0;
 }