diff options
author | Christian Mollekopf <chrigi_1@fastmail.fm> | 2017-10-26 13:05:04 +0200 |
---|---|---|
committer | Christian Mollekopf <chrigi_1@fastmail.fm> | 2017-10-26 13:05:04 +0200 |
commit | ecbd3b67e3f6e2bd3025b1fb9c734335612e554e (patch) | |
tree | f20b20dca3b6621834c167b870ac453f3bf9afc1 | |
parent | 6db02b1f5b3d47578e1bc0a9bb7ca85da2fe2de8 (diff) | |
download | sink-ecbd3b67e3f6e2bd3025b1fb9c734335612e554e.tar.gz sink-ecbd3b67e3f6e2bd3025b1fb9c734335612e554e.zip |
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.
-rw-r--r-- | common/mailpreprocessor.cpp | 33 | ||||
-rw-r--r-- | 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) | |||
37 | struct MimeMessageReader { | 37 | struct MimeMessageReader { |
38 | MimeMessageReader(const QString &mimeMessagePath) | 38 | MimeMessageReader(const QString &mimeMessagePath) |
39 | : f(mimeMessagePath), | 39 | : f(mimeMessagePath), |
40 | mapped(0), | 40 | mapped(0) |
41 | mappedSize(0) | ||
42 | { | 41 | { |
43 | if (mimeMessagePath.isNull()) { | 42 | if (mimeMessagePath.isNull()) { |
44 | SinkTrace() << "No mime message"; | 43 | SinkTrace() << "No mime message"; |
@@ -53,8 +52,7 @@ struct MimeMessageReader { | |||
53 | SinkWarning() << "The file is empty."; | 52 | SinkWarning() << "The file is empty."; |
54 | return; | 53 | return; |
55 | } | 54 | } |
56 | mappedSize = qMin((qint64)8000, f.size()); | 55 | mapped = f.map(0, f.size()); |
57 | mapped = f.map(0, mappedSize); | ||
58 | if (!mapped) { | 56 | if (!mapped) { |
59 | SinkWarning() << "Failed to map the file: " << f.errorString(); | 57 | SinkWarning() << "Failed to map the file: " << f.errorString(); |
60 | return; | 58 | return; |
@@ -64,19 +62,30 @@ struct MimeMessageReader { | |||
64 | KMime::Message::Ptr mimeMessage() | 62 | KMime::Message::Ptr mimeMessage() |
65 | { | 63 | { |
66 | if (!mapped) { | 64 | if (!mapped) { |
67 | return KMime::Message::Ptr(); | 65 | return {}; |
68 | } | 66 | } |
69 | Q_ASSERT(mapped); | 67 | QByteArray result; |
70 | Q_ASSERT(mappedSize); | 68 | //Seek for end of headers |
71 | auto msg = KMime::Message::Ptr(new KMime::Message); | 69 | const auto content = QByteArray::fromRawData(reinterpret_cast<const char*>(mapped), f.size()); |
72 | msg->setHead(KMime::CRLFtoLF(QByteArray::fromRawData(reinterpret_cast<const char*>(mapped), mappedSize))); | 70 | int pos = content.indexOf("\r\n\r\n", 0); |
73 | msg->parse(); | 71 | int offset = 2; |
74 | return msg; | 72 | if (pos < 0) { |
73 | pos = content.indexOf("\n\n", 0); | ||
74 | offset = 1; | ||
75 | } | ||
76 | if (pos > -1) { | ||
77 | const auto header = content.left(pos + offset); //header *must* end with "\n" !! | ||
78 | auto msg = KMime::Message::Ptr(new KMime::Message); | ||
79 | msg->setHead(KMime::CRLFtoLF(header)); | ||
80 | msg->parse(); | ||
81 | return msg; | ||
82 | } | ||
83 | SinkWarning() << "Failed to find end of headers" << content; | ||
84 | return {}; | ||
75 | } | 85 | } |
76 | 86 | ||
77 | QFile f; | 87 | QFile f; |
78 | uchar *mapped; | 88 | uchar *mapped; |
79 | qint64 mappedSize; | ||
80 | }; | 89 | }; |
81 | 90 | ||
82 | static Sink::ApplicationDomain::Mail::Contact getContact(const KMime::Headers::Generics::MailboxList *header) | 91 | 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) | |||
552 | qCWarning(log) << "Maildir::readEntryHeaders unable to find: " << file; | 552 | qCWarning(log) << "Maildir::readEntryHeaders unable to find: " << file; |
553 | return result; | 553 | return result; |
554 | } | 554 | } |
555 | f.map(0, qMin((qint64)8000, f.size())); | 555 | f.map(0, f.size()); |
556 | //Seek for end of headers | ||
556 | forever { | 557 | forever { |
557 | QByteArray line = f.readLine(); | 558 | QByteArray line = f.readLine(); |
558 | if (line.isEmpty() || line.startsWith('\n')) | 559 | if (line.isEmpty() || line.startsWith('\n')) |