Fixes/comments for guessBestEncoding (#304)
* tests: add case for getRecommendedEncoding * vmime: avoid integer multiply wraparound in wordEncoder::guessBestEncoding If the input string is 42949673 characters long or larger, there will be integer overflow on 32-bit platforms when multiplying by 100. Switch that one computation to floating point. * vmime: update comment in wordEncoder::guessBestEncoding
This commit is contained in:
parent
97d15b8cd7
commit
b447adbe37
@ -302,14 +302,16 @@ wordEncoder::Encoding wordEncoder::guessBestEncoding(
|
||||
}
|
||||
}
|
||||
|
||||
// Use Base64 if more than 40% non-ASCII, or Quoted-Printable else (default)
|
||||
// Base64 would be more space-efficient when the ASCII content is
|
||||
// below 83.33%, but QP has a legibility arugment going for it, so we
|
||||
// picked 60%.
|
||||
const size_t asciiCount =
|
||||
utility::stringUtils::countASCIIchars(buffer.begin(), buffer.end());
|
||||
|
||||
const size_t asciiPercent =
|
||||
buffer.length() == 0 ? 100 : (100 * asciiCount) / buffer.length();
|
||||
const double asciiPercent =
|
||||
buffer.length() == 0 ? 100 : static_cast<double>(asciiCount) / buffer.length();
|
||||
|
||||
if (asciiPercent < 60) {
|
||||
if (asciiPercent < 0.60) {
|
||||
return ENCODING_B64;
|
||||
} else {
|
||||
return ENCODING_QP;
|
||||
|
@ -32,6 +32,7 @@ VMIME_TEST_SUITE_BEGIN(textTest)
|
||||
VMIME_TEST_LIST_BEGIN
|
||||
VMIME_TEST(testConstructors)
|
||||
VMIME_TEST(testCopy)
|
||||
VMIME_TEST(testRecommendedEncoding)
|
||||
VMIME_TEST(testNewFromString)
|
||||
VMIME_TEST(testDisplayForm)
|
||||
VMIME_TEST(testParse)
|
||||
@ -155,6 +156,17 @@ VMIME_TEST_SUITE_BEGIN(textTest)
|
||||
VASSERT("copyFrom", t1 == t2);
|
||||
}
|
||||
|
||||
void testRecommendedEncoding() {
|
||||
|
||||
vmime::encoding enc;
|
||||
VASSERT_TRUE("1.1", vmime::charset("iso8859-1").getRecommendedEncoding(enc));
|
||||
VASSERT_TRUE("1.2", enc.getName() == vmime::encodingTypes::QUOTED_PRINTABLE);
|
||||
VASSERT_TRUE("1.2", vmime::charset("iso8859-2").getRecommendedEncoding(enc));
|
||||
VASSERT_TRUE("1.3", enc.getName() == vmime::encodingTypes::QUOTED_PRINTABLE);
|
||||
VASSERT_FALSE("1.3", vmime::charset(vmime::charsets::UTF_8).getRecommendedEncoding(enc));
|
||||
|
||||
}
|
||||
|
||||
void testNewFromString() {
|
||||
|
||||
vmime::string s1 = "only ASCII characters";
|
||||
|
@ -36,6 +36,7 @@ VMIME_TEST_SUITE_BEGIN(wordEncoderTest)
|
||||
VMIME_TEST(testIsEncodingNeeded_specialChars)
|
||||
VMIME_TEST(testGuessBestEncoding_QP)
|
||||
VMIME_TEST(testGuessBestEncoding_B64)
|
||||
VMIME_TEST(testGuessBestEncoding_size)
|
||||
VMIME_TEST(testEncodeQP_RFC2047)
|
||||
VMIME_TEST_LIST_END
|
||||
|
||||
@ -159,6 +160,14 @@ VMIME_TEST_SUITE_BEGIN(wordEncoderTest)
|
||||
);
|
||||
}
|
||||
|
||||
void testGuessBestEncoding_size() {
|
||||
|
||||
std::string i(42949673, 'a');
|
||||
auto enc = vmime::wordEncoder::guessBestEncoding(i, vmime::charset("utf-8"));
|
||||
VASSERT_EQ("1", enc, vmime::wordEncoder::ENCODING_QP);
|
||||
|
||||
}
|
||||
|
||||
void testEncodeQP_RFC2047() {
|
||||
|
||||
// When Quoted-Printable is used, it should be RFC-2047 QP encoding
|
||||
|
Loading…
Reference in New Issue
Block a user