Merge branch 'jk/format-patch-multiline-header' into maint
* jk/format-patch-multiline-header: format-patch: rfc2047-encode newlines in headers format-patch: wrap long header lines strbuf: add fixed-length version of add_wrapped_text
This commit is contained in:
commit
c3d1a4368a
36
pretty.c
36
pretty.c
@ -216,36 +216,53 @@ static int is_rfc2047_special(char ch)
|
||||
static void add_rfc2047(struct strbuf *sb, const char *line, int len,
|
||||
const char *encoding)
|
||||
{
|
||||
int i, last;
|
||||
static const int max_length = 78; /* per rfc2822 */
|
||||
int i;
|
||||
int line_len;
|
||||
|
||||
/* How many bytes are already used on the current line? */
|
||||
for (i = sb->len - 1; i >= 0; i--)
|
||||
if (sb->buf[i] == '\n')
|
||||
break;
|
||||
line_len = sb->len - (i+1);
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
int ch = line[i];
|
||||
if (non_ascii(ch))
|
||||
if (non_ascii(ch) || ch == '\n')
|
||||
goto needquote;
|
||||
if ((i + 1 < len) && (ch == '=' && line[i+1] == '?'))
|
||||
goto needquote;
|
||||
}
|
||||
strbuf_add(sb, line, len);
|
||||
strbuf_add_wrapped_bytes(sb, line, len, 0, 1, max_length - line_len);
|
||||
return;
|
||||
|
||||
needquote:
|
||||
strbuf_grow(sb, len * 3 + strlen(encoding) + 100);
|
||||
strbuf_addf(sb, "=?%s?q?", encoding);
|
||||
for (i = last = 0; i < len; i++) {
|
||||
line_len += strlen(encoding) + 5; /* 5 for =??q? */
|
||||
for (i = 0; i < len; i++) {
|
||||
unsigned ch = line[i] & 0xFF;
|
||||
|
||||
if (line_len >= max_length - 2) {
|
||||
strbuf_addf(sb, "?=\n =?%s?q?", encoding);
|
||||
line_len = strlen(encoding) + 5 + 1; /* =??q? plus SP */
|
||||
}
|
||||
|
||||
/*
|
||||
* We encode ' ' using '=20' even though rfc2047
|
||||
* allows using '_' for readability. Unfortunately,
|
||||
* many programs do not understand this and just
|
||||
* leave the underscore in place.
|
||||
*/
|
||||
if (is_rfc2047_special(ch) || ch == ' ') {
|
||||
strbuf_add(sb, line + last, i - last);
|
||||
if (is_rfc2047_special(ch) || ch == ' ' || ch == '\n') {
|
||||
strbuf_addf(sb, "=%02X", ch);
|
||||
last = i + 1;
|
||||
line_len += 3;
|
||||
}
|
||||
else {
|
||||
strbuf_addch(sb, ch);
|
||||
line_len++;
|
||||
}
|
||||
}
|
||||
strbuf_add(sb, line + last, len - last);
|
||||
strbuf_addstr(sb, "?=");
|
||||
}
|
||||
|
||||
@ -1106,11 +1123,10 @@ void pp_title_line(enum cmit_fmt fmt,
|
||||
const char *encoding,
|
||||
int need_8bit_cte)
|
||||
{
|
||||
const char *line_separator = (fmt == CMIT_FMT_EMAIL) ? "\n " : " ";
|
||||
struct strbuf title;
|
||||
|
||||
strbuf_init(&title, 80);
|
||||
*msg_p = format_subject(&title, *msg_p, line_separator);
|
||||
*msg_p = format_subject(&title, *msg_p, " ");
|
||||
|
||||
strbuf_grow(sb, title.len + 1024);
|
||||
if (subject) {
|
||||
|
@ -709,4 +709,88 @@ test_expect_success TTY 'format-patch --stdout paginates' '
|
||||
test_path_is_missing .git/pager_used
|
||||
'
|
||||
|
||||
test_expect_success 'format-patch handles multi-line subjects' '
|
||||
rm -rf patches/ &&
|
||||
echo content >>file &&
|
||||
for i in one two three; do echo $i; done >msg &&
|
||||
git add file &&
|
||||
git commit -F msg &&
|
||||
git format-patch -o patches -1 &&
|
||||
grep ^Subject: patches/0001-one.patch >actual &&
|
||||
echo "Subject: [PATCH] one two three" >expect &&
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
test_expect_success 'format-patch handles multi-line encoded subjects' '
|
||||
rm -rf patches/ &&
|
||||
echo content >>file &&
|
||||
for i in en två tre; do echo $i; done >msg &&
|
||||
git add file &&
|
||||
git commit -F msg &&
|
||||
git format-patch -o patches -1 &&
|
||||
grep ^Subject: patches/0001-en.patch >actual &&
|
||||
echo "Subject: [PATCH] =?UTF-8?q?en=20tv=C3=A5=20tre?=" >expect &&
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
M8="foo bar "
|
||||
M64=$M8$M8$M8$M8$M8$M8$M8$M8
|
||||
M512=$M64$M64$M64$M64$M64$M64$M64$M64
|
||||
cat >expect <<'EOF'
|
||||
Subject: [PATCH] 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 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 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
|
||||
EOF
|
||||
test_expect_success 'format-patch wraps extremely long headers (ascii)' '
|
||||
echo content >>file &&
|
||||
git add file &&
|
||||
git commit -m "$M512" &&
|
||||
git format-patch --stdout -1 >patch &&
|
||||
sed -n "/^Subject/p; /^ /p; /^$/q" <patch >subject &&
|
||||
test_cmp expect subject
|
||||
'
|
||||
|
||||
M8="föö bar "
|
||||
M64=$M8$M8$M8$M8$M8$M8$M8$M8
|
||||
M512=$M64$M64$M64$M64$M64$M64$M64$M64
|
||||
cat >expect <<'EOF'
|
||||
Subject: [PATCH] =?UTF-8?q?f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
|
||||
=?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
|
||||
=?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
|
||||
=?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
|
||||
=?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
|
||||
=?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
|
||||
=?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
|
||||
=?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
|
||||
=?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
|
||||
=?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
|
||||
=?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
|
||||
=?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
|
||||
=?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
|
||||
=?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
|
||||
=?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
|
||||
=?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
|
||||
=?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
|
||||
=?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
|
||||
=?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
|
||||
=?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
|
||||
=?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
|
||||
=?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
|
||||
EOF
|
||||
test_expect_success 'format-patch wraps extremely long headers (rfc2047)' '
|
||||
rm -rf patches/ &&
|
||||
echo content >>file &&
|
||||
git add file &&
|
||||
git commit -m "$M512" &&
|
||||
git format-patch --stdout -1 >patch &&
|
||||
sed -n "/^Subject/p; /^ /p; /^$/q" <patch >subject &&
|
||||
test_cmp expect subject
|
||||
'
|
||||
|
||||
test_done
|
||||
|
9
utf8.c
9
utf8.c
@ -405,6 +405,15 @@ new_line:
|
||||
}
|
||||
}
|
||||
|
||||
int strbuf_add_wrapped_bytes(struct strbuf *buf, const char *data, int len,
|
||||
int indent, int indent2, int width)
|
||||
{
|
||||
char *tmp = xstrndup(data, len);
|
||||
int r = strbuf_add_wrapped_text(buf, tmp, indent, indent2, width);
|
||||
free(tmp);
|
||||
return r;
|
||||
}
|
||||
|
||||
int is_encoding_utf8(const char *name)
|
||||
{
|
||||
if (!name)
|
||||
|
2
utf8.h
2
utf8.h
@ -10,6 +10,8 @@ int is_encoding_utf8(const char *name);
|
||||
|
||||
int strbuf_add_wrapped_text(struct strbuf *buf,
|
||||
const char *text, int indent, int indent2, int width);
|
||||
int strbuf_add_wrapped_bytes(struct strbuf *buf, const char *data, int len,
|
||||
int indent, int indent2, int width);
|
||||
|
||||
#ifndef NO_ICONV
|
||||
char *reencode_string(const char *in, const char *out_encoding, const char *in_encoding);
|
||||
|
Loading…
Reference in New Issue
Block a user