mailinfo: unescape quoted-pair in header fields

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

The only thing git currently does is removing exterior quotes, but
quotes within are left alone.

Remove exterior quotes and remove escape characters so that they don't
show up in the author field.

Signed-off-by: Kevin Daudt <me@ikke.info>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Kevin Daudt 2016-09-28 21:52:32 +02:00 коммит произвёл Junio C Hamano
Родитель ee4d679f57
Коммит f357e5de31
6 изменённых файлов: 124 добавлений и 0 удалений

Просмотреть файл

@ -54,6 +54,86 @@ static void parse_bogus_from(struct mailinfo *mi, const struct strbuf *line)
get_sane_name(&mi->name, &mi->name, &mi->email);
}
static const char *unquote_comment(struct strbuf *outbuf, const char *in)
{
int c;
int take_next_litterally = 0;
strbuf_addch(outbuf, '(');
while ((c = *in++) != 0) {
if (take_next_litterally == 1) {
take_next_litterally = 0;
} else {
switch (c) {
case '\\':
take_next_litterally = 1;
continue;
case '(':
in = unquote_comment(outbuf, in);
continue;
case ')':
strbuf_addch(outbuf, ')');
return in;
}
}
strbuf_addch(outbuf, c);
}
return in;
}
static const char *unquote_quoted_string(struct strbuf *outbuf, const char *in)
{
int c;
int take_next_litterally = 0;
while ((c = *in++) != 0) {
if (take_next_litterally == 1) {
take_next_litterally = 0;
} else {
switch (c) {
case '\\':
take_next_litterally = 1;
continue;
case '"':
return in;
}
}
strbuf_addch(outbuf, c);
}
return in;
}
static void unquote_quoted_pair(struct strbuf *line)
{
struct strbuf outbuf;
const char *in = line->buf;
int c;
strbuf_init(&outbuf, line->len);
while ((c = *in++) != 0) {
switch (c) {
case '"':
in = unquote_quoted_string(&outbuf, in);
continue;
case '(':
in = unquote_comment(&outbuf, in);
continue;
}
strbuf_addch(&outbuf, c);
}
strbuf_swap(&outbuf, line);
strbuf_release(&outbuf);
}
static void handle_from(struct mailinfo *mi, const struct strbuf *from)
{
char *at;
@ -63,6 +143,8 @@ static void handle_from(struct mailinfo *mi, const struct strbuf *from)
strbuf_init(&f, from->len);
strbuf_addbuf(&f, from);
unquote_quoted_pair(&f);
at = strchr(f.buf, '@');
if (!at) {
parse_bogus_from(mi, from);

Просмотреть файл

@ -144,4 +144,18 @@ test_expect_success 'mailinfo unescapes with --mboxrd' '
test_cmp expect mboxrd/msg
'
test_expect_success 'mailinfo handles rfc2822 quoted-string' '
mkdir quoted-string &&
git mailinfo /dev/null /dev/null <"$DATA/quoted-string.in" \
>quoted-string/info &&
test_cmp "$DATA/quoted-string.expect" quoted-string/info
'
test_expect_success 'mailinfo handles rfc2822 comment' '
mkdir comment &&
git mailinfo /dev/null /dev/null <"$DATA/comment.in" \
>comment/info &&
test_cmp "$DATA/comment.expect" comment/info
'
test_done

5
t/t5100/comment.expect Normal file
Просмотреть файл

@ -0,0 +1,5 @@
Author: A U Thor (this is (really) a comment (honestly))
Email: somebody@example.com
Subject: testing comments
Date: Sun, 25 May 2008 00:38:18 -0700

9
t/t5100/comment.in Normal file
Просмотреть файл

@ -0,0 +1,9 @@
From 1234567890123456789012345678901234567890 Mon Sep 17 00:00:00 2001
From: "A U Thor" <somebody@example.com> (this is \(really\) a comment (honestly))
Date: Sun, 25 May 2008 00:38:18 -0700
Subject: [PATCH] testing comments
---
patch

Просмотреть файл

@ -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

9
t/t5100/quoted-string.in Normal file
Просмотреть файл

@ -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