Skip to content

Commit 94f6cdf

Browse files
Jan H. Schönherrgitster
authored andcommitted
format-patch: do not wrap rfc2047 encoded headers too late
Encoded characters add more than one character at once to an encoded header. Include all characters that are about to be added in the length calculation for wrapping. Additionally, RFC 2047 imposes a maximum line length of 76 characters if that line contains an rfc2047 encoded word. Signed-off-by: Jan H. Schönherr <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 7a76e68 commit 94f6cdf

File tree

2 files changed

+51
-33
lines changed

2 files changed

+51
-33
lines changed

pretty.c

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -263,13 +263,17 @@ static void add_rfc822_quoted(struct strbuf *out, const char *s, int len)
263263

264264
static int is_rfc2047_special(char ch)
265265
{
266+
if (ch == ' ' || ch == '\n')
267+
return 1;
268+
266269
return (non_ascii(ch) || (ch == '=') || (ch == '?') || (ch == '_'));
267270
}
268271

269272
static void add_rfc2047(struct strbuf *sb, const char *line, int len,
270273
const char *encoding)
271274
{
272275
static const int max_length = 78; /* per rfc2822 */
276+
static const int max_encoded_length = 76; /* per rfc2047 */
273277
int i;
274278
int line_len;
275279

@@ -295,23 +299,25 @@ static void add_rfc2047(struct strbuf *sb, const char *line, int len,
295299
line_len += strlen(encoding) + 5; /* 5 for =??q? */
296300
for (i = 0; i < len; i++) {
297301
unsigned ch = line[i] & 0xFF;
302+
int is_special = is_rfc2047_special(ch);
303+
304+
/*
305+
* According to RFC 2047, we could encode the special character
306+
* ' ' (space) with '_' (underscore) for readability. But many
307+
* programs do not understand this and just leave the
308+
* underscore in place. Thus, we do nothing special here, which
309+
* causes ' ' to be encoded as '=20', avoiding this problem.
310+
*/
298311

299-
if (line_len >= max_length - 2) {
312+
if (line_len + 2 + (is_special ? 3 : 1) > max_encoded_length) {
300313
strbuf_addf(sb, "?=\n =?%s?q?", encoding);
301314
line_len = strlen(encoding) + 5 + 1; /* =??q? plus SP */
302315
}
303316

304-
/*
305-
* We encode ' ' using '=20' even though rfc2047
306-
* allows using '_' for readability. Unfortunately,
307-
* many programs do not understand this and just
308-
* leave the underscore in place.
309-
*/
310-
if (is_rfc2047_special(ch) || ch == ' ' || ch == '\n') {
317+
if (is_special) {
311318
strbuf_addf(sb, "=%02X", ch);
312319
line_len += 3;
313-
}
314-
else {
320+
} else {
315321
strbuf_addch(sb, ch);
316322
line_len++;
317323
}

t/t4014-format-patch.sh

Lines changed: 35 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -772,30 +772,31 @@ M8="föö bar "
772772
M64=$M8$M8$M8$M8$M8$M8$M8$M8
773773
M512=$M64$M64$M64$M64$M64$M64$M64$M64
774774
cat >expect <<'EOF'
775-
Subject: [PATCH] =?UTF-8?q?f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
776-
=?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
777-
=?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
778-
=?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
779-
=?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
780-
=?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
781-
=?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
782-
=?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
783-
=?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
784-
=?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
785-
=?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
786-
=?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
787-
=?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
788-
=?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
789-
=?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
790-
=?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
791-
=?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
792-
=?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
793-
=?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
794-
=?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
795-
=?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
796-
=?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
775+
Subject: [PATCH] =?UTF-8?q?f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
776+
=?UTF-8?q?=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
777+
=?UTF-8?q?=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20?=
778+
=?UTF-8?q?bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6?=
779+
=?UTF-8?q?=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3?=
780+
=?UTF-8?q?=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
781+
=?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3?=
782+
=?UTF-8?q?=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
783+
=?UTF-8?q?=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
784+
=?UTF-8?q?=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20?=
785+
=?UTF-8?q?bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6?=
786+
=?UTF-8?q?=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3?=
787+
=?UTF-8?q?=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
788+
=?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3?=
789+
=?UTF-8?q?=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
790+
=?UTF-8?q?=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
791+
=?UTF-8?q?=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20?=
792+
=?UTF-8?q?bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6?=
793+
=?UTF-8?q?=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3?=
794+
=?UTF-8?q?=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
795+
=?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3?=
796+
=?UTF-8?q?=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
797+
=?UTF-8?q?=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
797798
EOF
798-
test_expect_success 'format-patch wraps extremely long headers (rfc2047)' '
799+
test_expect_success 'format-patch wraps extremely long subject (rfc2047)' '
799800
rm -rf patches/ &&
800801
echo content >>file &&
801802
git add file &&
@@ -861,6 +862,17 @@ test_expect_success 'format-patch wraps extremely long from-header (rfc822)' '
861862
check_author "Foo.Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar"
862863
'
863864

865+
cat >expect <<'EOF'
866+
From: =?UTF-8?q?Fo=C3=B6=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo?=
867+
=?UTF-8?q?=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20?=
868+
=?UTF-8?q?Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar?=
869+
=?UTF-8?q?=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20?=
870+
=?UTF-8?q?Foo=20Bar=20Foo=20Bar?= <[email protected]>
871+
EOF
872+
test_expect_success 'format-patch wraps extremely long from-header (rfc2047)' '
873+
check_author "Foö Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar"
874+
'
875+
864876
cat >expect <<'EOF'
865877
Subject: header with . in it
866878
EOF

0 commit comments

Comments
 (0)