From ecbd3b67e3f6e2bd3025b1fb9c734335612e554e Mon Sep 17 00:00:00 2001 From: Christian Mollekopf Date: Thu, 26 Oct 2017 13:05:04 +0200 Subject: Fixed parsing of larger headers. Just truncating the file is not a good idea. If the headers end up being larger (I just ran into that), then we just fail to parse the headers and miss important stuff like subjects. So let's not. --- common/mailpreprocessor.cpp | 33 ++++++++++++++++--------- examples/maildirresource/libmaildir/maildir.cpp | 3 ++- 2 files changed, 23 insertions(+), 13 deletions(-) diff --git a/common/mailpreprocessor.cpp b/common/mailpreprocessor.cpp index 253e8b4..b1cb1d5 100644 --- a/common/mailpreprocessor.cpp +++ b/common/mailpreprocessor.cpp @@ -37,8 +37,7 @@ QString MailPropertyExtractor::getFilePathFromMimeMessagePath(const QString &s) struct MimeMessageReader { MimeMessageReader(const QString &mimeMessagePath) : f(mimeMessagePath), - mapped(0), - mappedSize(0) + mapped(0) { if (mimeMessagePath.isNull()) { SinkTrace() << "No mime message"; @@ -53,8 +52,7 @@ struct MimeMessageReader { SinkWarning() << "The file is empty."; return; } - mappedSize = qMin((qint64)8000, f.size()); - mapped = f.map(0, mappedSize); + mapped = f.map(0, f.size()); if (!mapped) { SinkWarning() << "Failed to map the file: " << f.errorString(); return; @@ -64,19 +62,30 @@ struct MimeMessageReader { KMime::Message::Ptr mimeMessage() { if (!mapped) { - return KMime::Message::Ptr(); + return {}; } - Q_ASSERT(mapped); - Q_ASSERT(mappedSize); - auto msg = KMime::Message::Ptr(new KMime::Message); - msg->setHead(KMime::CRLFtoLF(QByteArray::fromRawData(reinterpret_cast(mapped), mappedSize))); - msg->parse(); - return msg; + QByteArray result; + //Seek for end of headers + const auto content = QByteArray::fromRawData(reinterpret_cast(mapped), f.size()); + int pos = content.indexOf("\r\n\r\n", 0); + int offset = 2; + if (pos < 0) { + pos = content.indexOf("\n\n", 0); + offset = 1; + } + if (pos > -1) { + const auto header = content.left(pos + offset); //header *must* end with "\n" !! + auto msg = KMime::Message::Ptr(new KMime::Message); + msg->setHead(KMime::CRLFtoLF(header)); + msg->parse(); + return msg; + } + SinkWarning() << "Failed to find end of headers" << content; + return {}; } QFile f; uchar *mapped; - qint64 mappedSize; }; static Sink::ApplicationDomain::Mail::Contact getContact(const KMime::Headers::Generics::MailboxList *header) diff --git a/examples/maildirresource/libmaildir/maildir.cpp b/examples/maildirresource/libmaildir/maildir.cpp index 203f6a6..83ad5ff 100644 --- a/examples/maildirresource/libmaildir/maildir.cpp +++ b/examples/maildirresource/libmaildir/maildir.cpp @@ -552,7 +552,8 @@ QByteArray Maildir::readEntryHeadersFromFile(const QString& file) qCWarning(log) << "Maildir::readEntryHeaders unable to find: " << file; return result; } - f.map(0, qMin((qint64)8000, f.size())); + f.map(0, f.size()); + //Seek for end of headers forever { QByteArray line = f.readLine(); if (line.isEmpty() || line.startsWith('\n')) -- cgit v1.2.3