diff options
author | Don Sanders <don.sanders@nokia.com> | 2011-06-06 21:52:15 +0300 |
---|---|---|
committer | Don Sanders <don.sanders@nokia.com> | 2011-06-06 21:52:15 +0300 |
commit | 781a79e8838959ad360e230caf4905141227d0f4 (patch) | |
tree | 61f23eb3490f96df4f19747ffc35f365af6f3067 | |
parent | a1b12ac205a8d2365435b086ec4877b77c4acefb (diff) |
Don't malloc bomb on ridiculously long header fields.
-rw-r--r-- | src/libraries/qmfclient/qmailmessage.cpp | 141 |
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); } } |