summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDon Sanders <don.sanders@nokia.com>2011-06-06 21:52:15 +0300
committerDon Sanders <don.sanders@nokia.com>2011-06-06 21:52:15 +0300
commit781a79e8838959ad360e230caf4905141227d0f4 (patch)
tree61f23eb3490f96df4f19747ffc35f365af6f3067
parenta1b12ac205a8d2365435b086ec4877b77c4acefb (diff)
Don't malloc bomb on ridiculously long header fields.
-rw-r--r--src/libraries/qmfclient/qmailmessage.cpp141
1 files changed, 76 insertions, 65 deletions
diff --git a/src/libraries/qmfclient/qmailmessage.cpp b/src/libraries/qmfclient/qmailmessage.cpp
index b1fe681c..d14ca25d 100644
--- a/src/libraries/qmfclient/qmailmessage.cpp
+++ b/src/libraries/qmfclient/qmailmessage.cpp
@@ -1899,85 +1899,96 @@ QByteArray QMailMessageHeaderFieldPrivate::toString(bool includeName, bool prese
return result;
}
-static void outputHeaderPart(QDataStream& out, const QByteArray& text, int* lineLength, const int maxLineLength)
+static void outputHeaderPart(QDataStream& out, const QByteArray& inText, int* lineLength, const int maxLineLength)
{
+ const int maxHeaderLength(10000);
+ QByteArray text(inText);
QRegExp whitespace("\\s");
QRegExp syntacticBreak(";|,");
- int remaining = maxLineLength - *lineLength;
- if (text.length() <= remaining)
- {
- out << DataString(text);
- *lineLength += text.length();
+ if (text.length() > maxHeaderLength) {
+ qWarning() << "Maximum header length exceeded, truncating mail header";
+ text.truncate(maxHeaderLength);
}
- else
- {
- // See if we can find suitable whitespace to break the line
- int wsIndex = -1;
- int lastIndex = -1;
- int preferredIndex = -1;
- bool syntacticBreakUsed = false;
- do
- {
- lastIndex = wsIndex;
- if ((lastIndex > 0)
- && ((text[lastIndex - 1] == ';') || (text[lastIndex - 1] == ','))) {
- // Prefer to split after (possible) parameters and commas
- preferredIndex = lastIndex;
- }
-
- wsIndex = whitespace.indexIn(text, wsIndex + 1);
- } while ((wsIndex != -1) && (wsIndex < remaining));
- if (preferredIndex != -1)
- lastIndex = preferredIndex;
-
- if (lastIndex == -1)
+ while (true) {
+ int remaining = maxLineLength - *lineLength;
+ if (text.length() <= remaining)
{
- // We couldn't find any suitable whitespace, look for high-level syntactic break
- // allow a maximum of 998 characters excl CRLF on a line without white space
- remaining = 997 - *lineLength;
- int syntacticIn = -1;
- do {
- lastIndex = syntacticIn;
- syntacticIn = syntacticBreak.indexIn(text, syntacticIn + 1);
- } while ((syntacticIn != -1) && (syntacticIn < remaining - 1));
-
- if (lastIndex != -1) {
- syntacticBreakUsed = true;
- ++lastIndex;
- } else {
- // We couldn't find any high-level syntactic break either - just break at the last char
- //qWarning() << "Unable to break header field at white space or syntactic break";
- lastIndex = remaining;
- }
- }
-
- if (lastIndex == 0)
- {
- out << DataString('\n') << DataString(text[0]);
- *lineLength = 1;
- lastIndex = 1;
+ out << DataString(text);
+ *lineLength += text.length();
+ return;
}
else
{
- out << DataString(text.left(lastIndex)) << DataString('\n');
+ // See if we can find suitable whitespace to break the line
+ int wsIndex = -1;
+ int lastIndex = -1;
+ int preferredIndex = -1;
+ bool syntacticBreakUsed = false;
+ do
+ {
+ lastIndex = wsIndex;
+ if ((lastIndex > 0)
+ && ((text[lastIndex - 1] == ';') || (text[lastIndex - 1] == ','))) {
+ // Prefer to split after (possible) parameters and commas
+ preferredIndex = lastIndex;
+ }
+
+ wsIndex = whitespace.indexIn(text, wsIndex + 1);
+ } while ((wsIndex != -1) && (wsIndex < remaining));
+
+ if (preferredIndex != -1)
+ lastIndex = preferredIndex;
+
+ if (lastIndex == -1)
+ {
+ // We couldn't find any suitable whitespace, look for high-level syntactic break
+ // allow a maximum of 998 characters excl CRLF on a line without white space
+ remaining = 997 - *lineLength;
+ int syntacticIn = -1;
+ do {
+ lastIndex = syntacticIn;
+ syntacticIn = syntacticBreak.indexIn(text, syntacticIn + 1);
+ } while ((syntacticIn != -1) && (syntacticIn < remaining - 1));
+
+ if (lastIndex != -1) {
+ syntacticBreakUsed = true;
+ ++lastIndex;
+ } else {
+ // We couldn't find any high-level syntactic break either - just break at the last char
+ //qWarning() << "Unable to break header field at white space or syntactic break";
+ lastIndex = remaining;
+ }
+ }
- if ((lastIndex == remaining) || (syntacticBreakUsed)) {
- // We need to insert some artifical whitespace
- out << DataString(' ');
- } else {
- // Append the breaking whitespace (ensure it does not get CRLF-ified)
- out << DataString(QByteArray(1, text[lastIndex]));
- ++lastIndex;
+ if (lastIndex == 0)
+ {
+ out << DataString('\n') << DataString(text[0]);
+ *lineLength = 1;
+ lastIndex = 1;
+ }
+ else
+ {
+ out << DataString(text.left(lastIndex)) << DataString('\n');
+
+ if ((lastIndex == remaining) || (syntacticBreakUsed)) {
+ // We need to insert some artifical whitespace
+ out << DataString(' ');
+ } else {
+ // Append the breaking whitespace (ensure it does not get CRLF-ified)
+ out << DataString(QByteArray(1, text[lastIndex]));
+ ++lastIndex;
+ }
+
+ *lineLength = 1;
}
- *lineLength = 1;
+ text = text.mid(lastIndex);
+ if (text.isEmpty()) {
+ return;
+ }
}
-
- QByteArray remainder(text.mid(lastIndex));
- if (!remainder.isEmpty())
- outputHeaderPart(out, remainder, lineLength, maxLineLength);
}
}