Skip to content

Commit 41dd00b

Browse files
Jan H. Schönherrgitster
authored andcommitted
format-patch: fix rfc2047 address encoding with respect to rfc822 specials
According to RFC 2047 and RFC 822, rfc2047 encoded words and and rfc822 quoted strings do not mix. Since add_rfc2047() no longer leaves RFC 822 specials behind, the quoting is also no longer necessary to create a standard-conforming mail. Remove the quoting, when RFC 2047 encoding takes place. This actually requires to refactor add_rfc2047() a bit, so that the different cases can be distinguished. With this patch, my own name gets correctly decoded as Jan H. Schönherr (without quotes) and not as "Jan H. Schönherr" (with quotes). Signed-off-by: Jan H. Schönherr <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 0fcec2c commit 41dd00b

File tree

2 files changed

+33
-18
lines changed

2 files changed

+33
-18
lines changed

pretty.c

Lines changed: 32 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,7 @@ static int is_rfc822_special(char ch)
231231
}
232232
}
233233

234-
static int has_rfc822_specials(const char *s, int len)
234+
static int needs_rfc822_quoting(const char *s, int len)
235235
{
236236
int i;
237237
for (i = 0; i < len; i++)
@@ -329,25 +329,29 @@ static int is_rfc2047_special(char ch, enum rfc2047_type type)
329329
return !(isalnum(ch) || ch == '!' || ch == '*' || ch == '+' || ch == '-' || ch == '/');
330330
}
331331

332-
static void add_rfc2047(struct strbuf *sb, const char *line, int len,
333-
const char *encoding, enum rfc2047_type type)
332+
static int needs_rfc2047_encoding(const char *line, int len,
333+
enum rfc2047_type type)
334334
{
335-
static const int max_length = 78; /* per rfc2822 */
336-
static const int max_encoded_length = 76; /* per rfc2047 */
337335
int i;
338-
int line_len = last_line_length(sb);
339336

340337
for (i = 0; i < len; i++) {
341338
int ch = line[i];
342339
if (non_ascii(ch) || ch == '\n')
343-
goto needquote;
340+
return 1;
344341
if ((i + 1 < len) && (ch == '=' && line[i+1] == '?'))
345-
goto needquote;
342+
return 1;
346343
}
347-
strbuf_add_wrapped_bytes(sb, line, len, -line_len, 1, max_length);
348-
return;
349344

350-
needquote:
345+
return 0;
346+
}
347+
348+
static void add_rfc2047(struct strbuf *sb, const char *line, int len,
349+
const char *encoding, enum rfc2047_type type)
350+
{
351+
static const int max_encoded_length = 76; /* per rfc2047 */
352+
int i;
353+
int line_len = last_line_length(sb);
354+
351355
strbuf_grow(sb, len * 3 + strlen(encoding) + 100);
352356
strbuf_addf(sb, "=?%s?q?", encoding);
353357
line_len += strlen(encoding) + 5; /* 5 for =??q? */
@@ -383,6 +387,7 @@ void pp_user_info(const struct pretty_print_context *pp,
383387
const char *what, struct strbuf *sb,
384388
const char *line, const char *encoding)
385389
{
390+
int max_length = 78; /* per rfc2822 */
386391
char *date;
387392
int namelen;
388393
unsigned long time;
@@ -406,17 +411,21 @@ void pp_user_info(const struct pretty_print_context *pp,
406411
name_tail--;
407412
display_name_length = name_tail - line;
408413
strbuf_addstr(sb, "From: ");
409-
if (!has_rfc822_specials(line, display_name_length)) {
414+
if (needs_rfc2047_encoding(line, display_name_length, RFC2047_ADDRESS)) {
410415
add_rfc2047(sb, line, display_name_length,
411416
encoding, RFC2047_ADDRESS);
412-
} else {
417+
max_length = 76; /* per rfc2047 */
418+
} else if (needs_rfc822_quoting(line, display_name_length)) {
413419
struct strbuf quoted = STRBUF_INIT;
414420
add_rfc822_quoted(&quoted, line, display_name_length);
415-
add_rfc2047(sb, quoted.buf, quoted.len,
416-
encoding, RFC2047_ADDRESS);
421+
strbuf_add_wrapped_bytes(sb, quoted.buf, quoted.len,
422+
-6, 1, max_length);
417423
strbuf_release(&quoted);
424+
} else {
425+
strbuf_add_wrapped_bytes(sb, line, display_name_length,
426+
-6, 1, max_length);
418427
}
419-
if (namelen - display_name_length + last_line_length(sb) > 78) {
428+
if (namelen - display_name_length + last_line_length(sb) > max_length) {
420429
strbuf_addch(sb, '\n');
421430
if (!isspace(name_tail[0]))
422431
strbuf_addch(sb, ' ');
@@ -1336,6 +1345,7 @@ void pp_title_line(const struct pretty_print_context *pp,
13361345
const char *encoding,
13371346
int need_8bit_cte)
13381347
{
1348+
static const int max_length = 78; /* per rfc2047 */
13391349
struct strbuf title;
13401350

13411351
strbuf_init(&title, 80);
@@ -1345,7 +1355,12 @@ void pp_title_line(const struct pretty_print_context *pp,
13451355
strbuf_grow(sb, title.len + 1024);
13461356
if (pp->subject) {
13471357
strbuf_addstr(sb, pp->subject);
1348-
add_rfc2047(sb, title.buf, title.len, encoding, RFC2047_SUBJECT);
1358+
if (needs_rfc2047_encoding(title.buf, title.len, RFC2047_SUBJECT))
1359+
add_rfc2047(sb, title.buf, title.len,
1360+
encoding, RFC2047_SUBJECT);
1361+
else
1362+
strbuf_add_wrapped_bytes(sb, title.buf, title.len,
1363+
-last_line_length(sb), 1, max_length);
13491364
} else {
13501365
strbuf_addbuf(sb, &title);
13511366
}

t/t4014-format-patch.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -839,7 +839,7 @@ test_expect_success 'format-patch uses rfc2047-encoded from-headers when necessa
839839
cat >expect <<'EOF'
840840
From: =?UTF-8?q?F=C3=B6o=20B=2E=20Bar?= <[email protected]>
841841
EOF
842-
test_expect_failure 'rfc2047-encoded from-headers leave no rfc822 specials' '
842+
test_expect_success 'rfc2047-encoded from-headers leave no rfc822 specials' '
843843
check_author "Föo B. Bar"
844844
'
845845

0 commit comments

Comments
 (0)