git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[RFC 0/1] mailinfo: de-quote quoted-pair in header fields

From
Kevin Daudt <me@ikke.info>
Date
Sep 13, 2016, 23:46 UTC
Message-ID
<20160913234612.22806-2-me@ikke.info>
In-Reply-To
<20160913234612.22806-1-me@ikke.info>

rfc2822 has provisions for quoted strings in structured header fields, but also allows for escaping these with so-called quoted-pairs.

git currently does not do anything with this at all, and verbatim takes over the field body.

Make sure to properly dequote these quoted-strings and comments.
Signed-off-by: Kevin Daudt <me@ikke.info>
---
 mailinfo.c                 | 46 ++++++++++++++++++++++++++++++++++++++++++++++
 t/t5100-mailinfo.sh        |  5 +++++
 t/t5100/quoted-pair.expect |  5 +++++
 t/t5100/quoted-pair.in     |  9 +++++++++
 t/t5100/quoted-pair.info   |  5 +++++
 5 files changed, 70 insertions(+)
 create mode 100644 t/t5100/quoted-pair.expect
 create mode 100644 t/t5100/quoted-pair.in
 create mode 100644 t/t5100/quoted-pair.info
diff --git a/mailinfo.c b/mailinfo.c
index e19abe3..3b7ae8a 100644
--- a/mailinfo.c
+++ b/mailinfo.c
@@ -445,6 +445,51 @@ static void decode_header(struct mailinfo *mi, struct strbuf *it)
 		mi->input_error = -1;
 }
 
+static int unescape_quoted_pair(struct mailinfo *mi, struct strbuf *line)
+{
+	struct strbuf outbuf = STRBUF_INIT;
+	const char *in = line->buf;
+	int c, skip=0;
+	char escape_context=0;
+
+	while ((c = *in++) != 0) {
+		if (!skip) {
+			switch (c) {
+				case '"':
+					if (!escape_context)
+						escape_context = '"';
+					else if (escape_context == '"')
+						escape_context = 0;
+					break;
+				case '\\':
+					if (escape_context) {
+						skip = 1;
+						continue;
+					}
+					break;
+				case '(':
+					if (!escape_context)
+						escape_context = '(';
+					break;
+				case ')':
+					if (escape_context == '(')
+						escape_context = 0;
+					break;
+			}
+		} else {
+			skip = 0;
+		}
+
+		strbuf_addch(&outbuf, c);
+	}
+
+	strbuf_reset(line);
+	strbuf_addbuf(line, &outbuf);
+
+	return 0;
+
+}
+
 static int check_header(struct mailinfo *mi,
 			const struct strbuf *line,
 			struct strbuf *hdr_data[], int overwrite)
@@ -461,6 +506,7 @@ static int check_header(struct mailinfo *mi,
 			 */
 			strbuf_add(&sb, line->buf + len + 2, line->len - len - 2);
 			decode_header(mi, &sb);
+			unescape_quoted_pair(mi, &sb);
 			handle_header(&hdr_data[i], &sb);
 			ret = 1;
 			goto check_header_out;
diff --git a/t/t5100-mailinfo.sh b/t/t5100-mailinfo.sh
index 1a5a546..2be61bf 100755
--- a/t/t5100-mailinfo.sh
+++ b/t/t5100-mailinfo.sh
@@ -142,4 +142,9 @@ test_expect_success 'mailinfo unescapes with --mboxrd' '
 	test_cmp expect mboxrd/msg
 '
 
+test_expect_success 'mailinfo unescapes rfc2822 quoted-pair' '
+    git mailinfo /dev/null /dev/null <"$TEST_DIRECTORY"/t5100/quoted-pair.in >"$TEST_DIRECTORY"/t5100/quoted-pair.info &&
+    test_cmp "$TEST_DIRECTORY"/t5100/quoted-pair.expect "$TEST_DIRECTORY"/t5100/quoted-pair.info
+'
+
 test_done
diff --git a/t/t5100/quoted-pair.expect b/t/t5100/quoted-pair.expect
new file mode 100644
index 0000000..9fe72e9
--- /dev/null
+++ b/t/t5100/quoted-pair.expect
@@ -0,0 +1,5 @@
+Author: "Author "The Author" Name"
+Email: somebody@example.com
+Subject: testing quoted-pair
+Date: Sun, 25 May 2008 00:38:18 -0700
+
diff --git a/t/t5100/quoted-pair.in b/t/t5100/quoted-pair.in
new file mode 100644
index 0000000..e2e627a
--- /dev/null
+++ b/t/t5100/quoted-pair.in
@@ -0,0 +1,9 @@
+From 1234567890123456789012345678901234567890 Mon Sep 17 00:00:00 2001
+From: "Author \"The Author\" Name" <somebody@example.com>
+Date: Sun, 25 May 2008 00:38:18 -0700
+Subject: [PATCH] testing quoted-pair
+
+
+
+---
+patch
diff --git a/t/t5100/quoted-pair.info b/t/t5100/quoted-pair.info
new file mode 100644
index 0000000..9fe72e9
--- /dev/null
+++ b/t/t5100/quoted-pair.info
@@ -0,0 +1,5 @@
+Author: "Author "The Author" Name"
+Email: somebody@example.com
+Subject: testing quoted-pair
+Date: Sun, 25 May 2008 00:38:18 -0700
+
-- 
2.10.0.rc2
Previous: Kevin DaudtNext: Junio C Hamano
Message 4 of 16 in “git-am includes escape characters from 'From' field”
  1. Swift GeekSep 12, 2016
  2. Jeff KingSep 13, 2016
  3. 0/1 de-quote quoted-strings in mailinfoKevin Daudt, Sep 13, 2016
  4. 0/1 mailinfo: de-quote quoted-pair in header fieldsKevin Daudt, Sep 13, 2016
  5. Junio C HamanoSep 14, 2016
  6. Kevin DaudtSep 14, 2016
  7. Jeff KingSep 14, 2016
  8. Junio C HamanoSep 14, 2016
  9. Kevin DaudtSep 14, 2016
  10. Junio C HamanoSep 14, 2016
  11. Jeff KingSep 14, 2016
  12. Junio C HamanoSep 14, 2016
  13. Jeff KingSep 14, 2016
  14. Kevin DaudtSep 15, 2016
  15. Jeff KingSep 15, 2016
  16. Jeff KingSep 14, 2016

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.