Avoid force-encoding display names that fit within qcontent
When the display name contains an At sign, or anything of the sort, libvmime would forcibly encode this to =?...?=, even if the line is fine ASCII which only needs quoting. rspamd takes excessive quoting as a sign of spam and penalizes such mails by raising the score (rule/match: TO_EXCESS_QP et al.)
This commit is contained in:
parent
6c4bd0dda9
commit
f4c611b736
@ -355,44 +355,14 @@ void mailbox::generateImpl(
|
||||
// - if it contains characters in a charset different from "US-ASCII",
|
||||
// - and/or if it contains one or more of these special chars:
|
||||
// CR LF TAB " ; , < > ( ) @ / ? . = :
|
||||
|
||||
// these special chars only require quoting, not full encoding
|
||||
// Check whether there are words that are not "US-ASCII"
|
||||
// and/or contain the special chars.
|
||||
bool forceEncode = false;
|
||||
|
||||
for (size_t w = 0 ; !forceEncode && w != m_name.getWordCount() ; ++w) {
|
||||
|
||||
if (m_name.getWordAt(w)->getCharset() == charset(charsets::US_ASCII)) {
|
||||
|
||||
const string& buffer = m_name.getWordAt(w)->getBuffer();
|
||||
|
||||
for (string::const_iterator c = buffer.begin() ;
|
||||
!forceEncode && c != buffer.end() ; ++c) {
|
||||
|
||||
switch (*c) {
|
||||
|
||||
case '\r':
|
||||
case '\n':
|
||||
case '\t':
|
||||
case ';':
|
||||
case ',':
|
||||
case '<': case '>':
|
||||
case '(': case ')':
|
||||
case '@':
|
||||
case '/':
|
||||
case '?':
|
||||
case '.':
|
||||
case '=':
|
||||
case ':':
|
||||
case '"':
|
||||
|
||||
forceEncode = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
if (m_name.getWordAt(w)->getCharset() != charset(charsets::US_ASCII)) {
|
||||
forceEncode = true;
|
||||
}
|
||||
}
|
||||
|
@ -31,7 +31,6 @@ VMIME_TEST_SUITE_BEGIN(bodyTest)
|
||||
VMIME_TEST(testGenerate_NonText)
|
||||
VMIME_TEST_LIST_END
|
||||
|
||||
|
||||
void testGenerate_Text() {
|
||||
|
||||
// RFC-2015: [Quoted-Printable encoding] A line break in a text body,
|
||||
|
@ -31,6 +31,7 @@ VMIME_TEST_SUITE_BEGIN(mailboxTest)
|
||||
VMIME_TEST(testEmptyEmailAddress)
|
||||
VMIME_TEST(testSeparatorInComment)
|
||||
VMIME_TEST(testMalformations)
|
||||
VMIME_TEST(testExcessiveQuoting)
|
||||
VMIME_TEST_LIST_END
|
||||
|
||||
|
||||
@ -170,4 +171,17 @@ VMIME_TEST_SUITE_BEGIN(mailboxTest)
|
||||
VASSERT_EQ("email", "bar@y.com", mbox.getEmail());
|
||||
}
|
||||
|
||||
void testExcessiveQuoting() {
|
||||
using namespace vmime;
|
||||
|
||||
// Check that ASCII display names are not encoded more than necessary
|
||||
emailAddress e("a@b.com");
|
||||
auto a = make_shared<mailbox>(text(word("Foo B@r", charsets::US_ASCII)), e);
|
||||
VASSERT_EQ("generate", "\"Foo B@r\" <a@b.com>", a->generate());
|
||||
VASSERT_NEQ("generate", "=?utf-8?Q?Foo_B=40r?= <a@b.com>", a->generate());
|
||||
|
||||
a = make_shared<mailbox>(text(word("Foo B@r", charsets::UTF_8)), e);
|
||||
VASSERT_EQ("generate", "=?utf-8?Q?Foo_B=40r?= <a@b.com>", a->generate());
|
||||
}
|
||||
|
||||
VMIME_TEST_SUITE_END
|
||||
|
Loading…
Reference in New Issue
Block a user