aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Engelhardt <[email protected]>2024-05-21 18:48:08 +0000
committerGitHub <[email protected]>2024-05-21 18:48:08 +0000
commita2636bd4ae2c9ed1b4a4a01324300ed1432fd40d (patch)
treef5e431c3440a08b2f95b5d7be4ee07e86a1321c9
parentvmime: prevent loss of a space during text::createFromString (#306) (diff)
downloadvmime-a2636bd4ae2c9ed1b4a4a01324300ed1432fd40d.tar.gz
vmime-a2636bd4ae2c9ed1b4a4a01324300ed1432fd40d.zip
asciiPercent computation: another potential multiplication overflow (#307)
* build: resolve a -Wconversion compiler warning wordEncoder.cpp:312:91: warning: conversion from ‘std::__cxx11::basic_string<char>::size_type’ {aka ‘long unsigned int’} to ‘double’ may change value [-Wconversion] 312 | buffer.length() == 0 ? 1 : static_cast<double>(asciiCount) / buffer.length(); | ~~~~~~~~~~~~~^~ * wordEncoder: replace value 100 for asciiPercent asciiPercent is a ratio, and not counting in units of hundredths anymore. The maximum value therefore should be 1 not 100. * vmime: avoid integer multiply wraparound in text::createFromString The change from commit v0.9.2-194-gb447adbe needs to be applied to one more function that replicates the same code. (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.)
-rw-r--r--src/vmime/text.cpp10
-rw-r--r--src/vmime/wordEncoder.cpp2
2 files changed, 5 insertions, 7 deletions
diff --git a/src/vmime/text.cpp b/src/vmime/text.cpp
index 08d27bb9..2c14110b 100644
--- a/src/vmime/text.cpp
+++ b/src/vmime/text.cpp
@@ -269,7 +269,7 @@ shared_ptr <text> text::newFromString(const string& in, const charset& ch) {
void text::createFromString(const string& in, const charset& ch) {
- size_t asciiPercent = 0;
+ double asciiPercent = 0;
removeAllWords();
@@ -282,14 +282,12 @@ void text::createFromString(const string& in, const charset& ch) {
if (!alwaysEncode) {
const auto asciiCount = utility::stringUtils::countASCIIchars(in.begin(), in.end());
- asciiPercent = (in.length() == 0 ? 100 : (100 * asciiCount) / in.length());
+ asciiPercent = in.length() == 0 ? 1 : static_cast<double>(asciiCount) / static_cast<double>(in.length());
}
- // If there are "too much" non-ASCII chars, produce just one
- // vmime::word. Because encoding happens word-wise, all of the input
- // gets encoded.
+ // Cf. wordEncoder::guessBestEncoding for details
- if (alwaysEncode || asciiPercent < 60) { // less than 60% ASCII chars
+ if (alwaysEncode || asciiPercent < 0.60) { // less than 60% ASCII chars
appendWord(make_shared <word>(in, ch));
return;
diff --git a/src/vmime/wordEncoder.cpp b/src/vmime/wordEncoder.cpp
index d1632022..404a57b4 100644
--- a/src/vmime/wordEncoder.cpp
+++ b/src/vmime/wordEncoder.cpp
@@ -309,7 +309,7 @@ wordEncoder::Encoding wordEncoder::guessBestEncoding(
utility::stringUtils::countASCIIchars(buffer.begin(), buffer.end());
const double asciiPercent =
- buffer.length() == 0 ? 100 : static_cast<double>(asciiCount) / buffer.length();
+ buffer.length() == 0 ? 1 : static_cast<double>(asciiCount) / static_cast<double>(buffer.length());
if (asciiPercent < 0.60) {
return ENCODING_B64;