Skip to content

Commit ace8ebb

Browse files
committed
Merge branch 'jk/format-patch-quote-special-in-from'
* jk/format-patch-quote-special-in-from: pretty: quote rfc822 specials in email addresses Conflicts: pretty.c t/t4014-format-patch.sh
2 parents 1273738 + 4d03c18 commit ace8ebb

File tree

2 files changed

+103
-1
lines changed

2 files changed

+103
-1
lines changed

pretty.c

Lines changed: 60 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,58 @@ int has_non_ascii(const char *s)
208208
return 0;
209209
}
210210

211+
static int is_rfc822_special(char ch)
212+
{
213+
switch (ch) {
214+
case '(':
215+
case ')':
216+
case '<':
217+
case '>':
218+
case '[':
219+
case ']':
220+
case ':':
221+
case ';':
222+
case '@':
223+
case ',':
224+
case '.':
225+
case '"':
226+
case '\\':
227+
return 1;
228+
default:
229+
return 0;
230+
}
231+
}
232+
233+
static int has_rfc822_specials(const char *s, int len)
234+
{
235+
int i;
236+
for (i = 0; i < len; i++)
237+
if (is_rfc822_special(s[i]))
238+
return 1;
239+
return 0;
240+
}
241+
242+
static void add_rfc822_quoted(struct strbuf *out, const char *s, int len)
243+
{
244+
int i;
245+
246+
/* just a guess, we may have to also backslash-quote */
247+
strbuf_grow(out, len + 2);
248+
249+
strbuf_addch(out, '"');
250+
for (i = 0; i < len; i++) {
251+
switch (s[i]) {
252+
case '"':
253+
case '\\':
254+
strbuf_addch(out, '\\');
255+
/* fall through */
256+
default:
257+
strbuf_addch(out, s[i]);
258+
}
259+
}
260+
strbuf_addch(out, '"');
261+
}
262+
211263
static int is_rfc2047_special(char ch)
212264
{
213265
return (non_ascii(ch) || (ch == '=') || (ch == '?') || (ch == '_'));
@@ -294,7 +346,14 @@ void pp_user_info(const char *what, enum cmit_fmt fmt, struct strbuf *sb,
294346
name_tail--;
295347
display_name_length = name_tail - line;
296348
strbuf_addstr(sb, "From: ");
297-
add_rfc2047(sb, line, display_name_length, encoding);
349+
if (!has_rfc822_specials(line, display_name_length)) {
350+
add_rfc2047(sb, line, display_name_length, encoding);
351+
} else {
352+
struct strbuf quoted = STRBUF_INIT;
353+
add_rfc822_quoted(&quoted, line, display_name_length);
354+
add_rfc2047(sb, quoted.buf, quoted.len, encoding);
355+
strbuf_release(&quoted);
356+
}
298357
for (final_line = 0; final_line < sb->len; final_line++)
299358
if (sb->buf[sb->len - final_line - 1] == '\n')
300359
break;

t/t4014-format-patch.sh

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -808,4 +808,47 @@ test_expect_success 'format-patch wraps non-quotable headers' '
808808
sed -n "/^From: /p; /^ /p; /^$/q" <patch >from &&
809809
test_cmp expect from
810810
'
811+
812+
check_author() {
813+
echo content >>file &&
814+
git add file &&
815+
GIT_AUTHOR_NAME=$1 git commit -m author-check &&
816+
git format-patch --stdout -1 >patch &&
817+
grep ^From: patch >actual &&
818+
test_cmp expect actual
819+
}
820+
821+
cat >expect <<'EOF'
822+
From: "Foo B. Bar" <[email protected]>
823+
EOF
824+
test_expect_success 'format-patch quotes dot in headers' '
825+
check_author "Foo B. Bar"
826+
'
827+
828+
cat >expect <<'EOF'
829+
From: "Foo \"The Baz\" Bar" <[email protected]>
830+
EOF
831+
test_expect_success 'format-patch quotes double-quote in headers' '
832+
check_author "Foo \"The Baz\" Bar"
833+
'
834+
835+
cat >expect <<'EOF'
836+
From: =?UTF-8?q?"F=C3=B6o=20B.=20Bar"?= <[email protected]>
837+
EOF
838+
test_expect_success 'rfc2047-encoded headers also double-quote 822 specials' '
839+
check_author "Föo B. Bar"
840+
'
841+
842+
cat >expect <<'EOF'
843+
Subject: header with . in it
844+
EOF
845+
test_expect_success 'subject lines do not have 822 atom-quoting' '
846+
echo content >>file &&
847+
git add file &&
848+
git commit -m "header with . in it" &&
849+
git format-patch -k -1 --stdout >patch &&
850+
grep ^Subject: patch >actual &&
851+
test_cmp expect actual
852+
'
853+
811854
test_done

0 commit comments

Comments
 (0)