Skip to content

Commit fe252ef

Browse files
committed
Merge branch 'kd/mailinfo-quoted-string'
An author name, that spelled a backslash-quoted double quote in the human readable part "My \"double quoted\" name", was not unquoted correctly while applying a patch from a piece of e-mail. * kd/mailinfo-quoted-string: mailinfo: unescape quoted-pair in header fields t5100-mailinfo: replace common path prefix with variable
2 parents e704c61 + f357e5d commit fe252ef

File tree

6 files changed

+159
-33
lines changed

6 files changed

+159
-33
lines changed

mailinfo.c

+82
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,86 @@ static void parse_bogus_from(struct mailinfo *mi, const struct strbuf *line)
5454
get_sane_name(&mi->name, &mi->name, &mi->email);
5555
}
5656

57+
static const char *unquote_comment(struct strbuf *outbuf, const char *in)
58+
{
59+
int c;
60+
int take_next_litterally = 0;
61+
62+
strbuf_addch(outbuf, '(');
63+
64+
while ((c = *in++) != 0) {
65+
if (take_next_litterally == 1) {
66+
take_next_litterally = 0;
67+
} else {
68+
switch (c) {
69+
case '\\':
70+
take_next_litterally = 1;
71+
continue;
72+
case '(':
73+
in = unquote_comment(outbuf, in);
74+
continue;
75+
case ')':
76+
strbuf_addch(outbuf, ')');
77+
return in;
78+
}
79+
}
80+
81+
strbuf_addch(outbuf, c);
82+
}
83+
84+
return in;
85+
}
86+
87+
static const char *unquote_quoted_string(struct strbuf *outbuf, const char *in)
88+
{
89+
int c;
90+
int take_next_litterally = 0;
91+
92+
while ((c = *in++) != 0) {
93+
if (take_next_litterally == 1) {
94+
take_next_litterally = 0;
95+
} else {
96+
switch (c) {
97+
case '\\':
98+
take_next_litterally = 1;
99+
continue;
100+
case '"':
101+
return in;
102+
}
103+
}
104+
105+
strbuf_addch(outbuf, c);
106+
}
107+
108+
return in;
109+
}
110+
111+
static void unquote_quoted_pair(struct strbuf *line)
112+
{
113+
struct strbuf outbuf;
114+
const char *in = line->buf;
115+
int c;
116+
117+
strbuf_init(&outbuf, line->len);
118+
119+
while ((c = *in++) != 0) {
120+
switch (c) {
121+
case '"':
122+
in = unquote_quoted_string(&outbuf, in);
123+
continue;
124+
case '(':
125+
in = unquote_comment(&outbuf, in);
126+
continue;
127+
}
128+
129+
strbuf_addch(&outbuf, c);
130+
}
131+
132+
strbuf_swap(&outbuf, line);
133+
strbuf_release(&outbuf);
134+
135+
}
136+
57137
static void handle_from(struct mailinfo *mi, const struct strbuf *from)
58138
{
59139
char *at;
@@ -63,6 +143,8 @@ static void handle_from(struct mailinfo *mi, const struct strbuf *from)
63143
strbuf_init(&f, from->len);
64144
strbuf_addbuf(&f, from);
65145

146+
unquote_quoted_pair(&f);
147+
66148
at = strchr(f.buf, '@');
67149
if (!at) {
68150
parse_bogus_from(mi, from);

t/t5100-mailinfo.sh

+49-33
Original file line numberDiff line numberDiff line change
@@ -7,45 +7,47 @@ test_description='git mailinfo and git mailsplit test'
77

88
. ./test-lib.sh
99

10+
DATA="$TEST_DIRECTORY/t5100"
11+
1012
test_expect_success 'split sample box' \
11-
'git mailsplit -o. "$TEST_DIRECTORY"/t5100/sample.mbox >last &&
13+
'git mailsplit -o. "$DATA/sample.mbox" >last &&
1214
last=$(cat last) &&
1315
echo total is $last &&
1416
test $(cat last) = 18'
1517

1618
check_mailinfo () {
1719
mail=$1 opt=$2
1820
mo="$mail$opt"
19-
git mailinfo -u $opt msg$mo patch$mo <$mail >info$mo &&
20-
test_cmp "$TEST_DIRECTORY"/t5100/msg$mo msg$mo &&
21-
test_cmp "$TEST_DIRECTORY"/t5100/patch$mo patch$mo &&
22-
test_cmp "$TEST_DIRECTORY"/t5100/info$mo info$mo
21+
git mailinfo -u $opt "msg$mo" "patch$mo" <"$mail" >"info$mo" &&
22+
test_cmp "$DATA/msg$mo" "msg$mo" &&
23+
test_cmp "$DATA/patch$mo" "patch$mo" &&
24+
test_cmp "$DATA/info$mo" "info$mo"
2325
}
2426

2527

2628
for mail in 00*
2729
do
2830
test_expect_success "mailinfo $mail" '
29-
check_mailinfo $mail "" &&
30-
if test -f "$TEST_DIRECTORY"/t5100/msg$mail--scissors
31+
check_mailinfo "$mail" "" &&
32+
if test -f "$DATA/msg$mail--scissors"
3133
then
32-
check_mailinfo $mail --scissors
34+
check_mailinfo "$mail" --scissors
3335
fi &&
34-
if test -f "$TEST_DIRECTORY"/t5100/msg$mail--no-inbody-headers
36+
if test -f "$DATA/msg$mail--no-inbody-headers"
3537
then
36-
check_mailinfo $mail --no-inbody-headers
38+
check_mailinfo "$mail" --no-inbody-headers
3739
fi &&
38-
if test -f "$TEST_DIRECTORY"/t5100/msg$mail--message-id
40+
if test -f "$DATA/msg$mail--message-id"
3941
then
40-
check_mailinfo $mail --message-id
42+
check_mailinfo "$mail" --message-id
4143
fi
4244
'
4345
done
4446

4547

4648
test_expect_success 'split box with rfc2047 samples' \
4749
'mkdir rfc2047 &&
48-
git mailsplit -orfc2047 "$TEST_DIRECTORY"/t5100/rfc2047-samples.mbox \
50+
git mailsplit -orfc2047 "$DATA/rfc2047-samples.mbox" \
4951
>rfc2047/last &&
5052
last=$(cat rfc2047/last) &&
5153
echo total is $last &&
@@ -54,73 +56,73 @@ test_expect_success 'split box with rfc2047 samples' \
5456
for mail in rfc2047/00*
5557
do
5658
test_expect_success "mailinfo $mail" '
57-
git mailinfo -u $mail-msg $mail-patch <$mail >$mail-info &&
59+
git mailinfo -u "$mail-msg" "$mail-patch" <"$mail" >"$mail-info" &&
5860
echo msg &&
59-
test_cmp "$TEST_DIRECTORY"/t5100/empty $mail-msg &&
61+
test_cmp "$DATA/empty" "$mail-msg" &&
6062
echo patch &&
61-
test_cmp "$TEST_DIRECTORY"/t5100/empty $mail-patch &&
63+
test_cmp "$DATA/empty" "$mail-patch" &&
6264
echo info &&
63-
test_cmp "$TEST_DIRECTORY"/t5100/rfc2047-info-$(basename $mail) $mail-info
65+
test_cmp "$DATA/rfc2047-info-$(basename $mail)" "$mail-info"
6466
'
6567
done
6668

6769
test_expect_success 'respect NULs' '
6870
69-
git mailsplit -d3 -o. "$TEST_DIRECTORY"/t5100/nul-plain &&
70-
test_cmp "$TEST_DIRECTORY"/t5100/nul-plain 001 &&
71+
git mailsplit -d3 -o. "$DATA/nul-plain" &&
72+
test_cmp "$DATA/nul-plain" 001 &&
7173
(cat 001 | git mailinfo msg patch) &&
7274
test_line_count = 4 patch
7375
7476
'
7577

7678
test_expect_success 'Preserve NULs out of MIME encoded message' '
7779
78-
git mailsplit -d5 -o. "$TEST_DIRECTORY"/t5100/nul-b64.in &&
79-
test_cmp "$TEST_DIRECTORY"/t5100/nul-b64.in 00001 &&
80+
git mailsplit -d5 -o. "$DATA/nul-b64.in" &&
81+
test_cmp "$DATA/nul-b64.in" 00001 &&
8082
git mailinfo msg patch <00001 &&
81-
test_cmp "$TEST_DIRECTORY"/t5100/nul-b64.expect patch
83+
test_cmp "$DATA/nul-b64.expect" patch
8284
8385
'
8486

8587
test_expect_success 'mailinfo on from header without name works' '
8688
8789
mkdir info-from &&
88-
git mailsplit -oinfo-from "$TEST_DIRECTORY"/t5100/info-from.in &&
89-
test_cmp "$TEST_DIRECTORY"/t5100/info-from.in info-from/0001 &&
90+
git mailsplit -oinfo-from "$DATA/info-from.in" &&
91+
test_cmp "$DATA/info-from.in" info-from/0001 &&
9092
git mailinfo info-from/msg info-from/patch \
9193
<info-from/0001 >info-from/out &&
92-
test_cmp "$TEST_DIRECTORY"/t5100/info-from.expect info-from/out
94+
test_cmp "$DATA/info-from.expect" info-from/out
9395
9496
'
9597

9698
test_expect_success 'mailinfo finds headers after embedded From line' '
9799
mkdir embed-from &&
98-
git mailsplit -oembed-from "$TEST_DIRECTORY"/t5100/embed-from.in &&
99-
test_cmp "$TEST_DIRECTORY"/t5100/embed-from.in embed-from/0001 &&
100+
git mailsplit -oembed-from "$DATA/embed-from.in" &&
101+
test_cmp "$DATA/embed-from.in" embed-from/0001 &&
100102
git mailinfo embed-from/msg embed-from/patch \
101103
<embed-from/0001 >embed-from/out &&
102-
test_cmp "$TEST_DIRECTORY"/t5100/embed-from.expect embed-from/out
104+
test_cmp "$DATA/embed-from.expect" embed-from/out
103105
'
104106

105107
test_expect_success 'mailinfo on message with quoted >From' '
106108
mkdir quoted-from &&
107-
git mailsplit -oquoted-from "$TEST_DIRECTORY"/t5100/quoted-from.in &&
108-
test_cmp "$TEST_DIRECTORY"/t5100/quoted-from.in quoted-from/0001 &&
109+
git mailsplit -oquoted-from "$DATA/quoted-from.in" &&
110+
test_cmp "$DATA/quoted-from.in" quoted-from/0001 &&
109111
git mailinfo quoted-from/msg quoted-from/patch \
110112
<quoted-from/0001 >quoted-from/out &&
111-
test_cmp "$TEST_DIRECTORY"/t5100/quoted-from.expect quoted-from/msg
113+
test_cmp "$DATA/quoted-from.expect" quoted-from/msg
112114
'
113115

114116
test_expect_success 'mailinfo unescapes with --mboxrd' '
115117
mkdir mboxrd &&
116118
git mailsplit -omboxrd --mboxrd \
117-
"$TEST_DIRECTORY"/t5100/sample.mboxrd >last &&
119+
"$DATA/sample.mboxrd" >last &&
118120
test x"$(cat last)" = x2 &&
119121
for i in 0001 0002
120122
do
121123
git mailinfo mboxrd/msg mboxrd/patch \
122124
<mboxrd/$i >mboxrd/out &&
123-
test_cmp "$TEST_DIRECTORY"/t5100/${i}mboxrd mboxrd/msg
125+
test_cmp "$DATA/${i}mboxrd" mboxrd/msg
124126
done &&
125127
sp=" " &&
126128
echo "From " >expect &&
@@ -142,4 +144,18 @@ test_expect_success 'mailinfo unescapes with --mboxrd' '
142144
test_cmp expect mboxrd/msg
143145
'
144146

147+
test_expect_success 'mailinfo handles rfc2822 quoted-string' '
148+
mkdir quoted-string &&
149+
git mailinfo /dev/null /dev/null <"$DATA/quoted-string.in" \
150+
>quoted-string/info &&
151+
test_cmp "$DATA/quoted-string.expect" quoted-string/info
152+
'
153+
154+
test_expect_success 'mailinfo handles rfc2822 comment' '
155+
mkdir comment &&
156+
git mailinfo /dev/null /dev/null <"$DATA/comment.in" \
157+
>comment/info &&
158+
test_cmp "$DATA/comment.expect" comment/info
159+
'
160+
145161
test_done

t/t5100/comment.expect

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
Author: A U Thor (this is (really) a comment (honestly))
2+
3+
Subject: testing comments
4+
Date: Sun, 25 May 2008 00:38:18 -0700
5+

t/t5100/comment.in

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
From 1234567890123456789012345678901234567890 Mon Sep 17 00:00:00 2001
2+
From: "A U Thor" <[email protected]> (this is \(really\) a comment (honestly))
3+
Date: Sun, 25 May 2008 00:38:18 -0700
4+
Subject: [PATCH] testing comments
5+
6+
7+
8+
---
9+
patch

t/t5100/quoted-string.expect

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
Author: Author "The Author" Name
2+
3+
Subject: testing quoted-pair
4+
Date: Sun, 25 May 2008 00:38:18 -0700
5+

t/t5100/quoted-string.in

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
From 1234567890123456789012345678901234567890 Mon Sep 17 00:00:00 2001
2+
From: "Author \"The Author\" Name" <[email protected]>
3+
Date: Sun, 25 May 2008 00:38:18 -0700
4+
Subject: [PATCH] testing quoted-pair
5+
6+
7+
8+
---
9+
patch

0 commit comments

Comments
 (0)