summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Mollekopf <chrigi_1@fastmail.fm>2017-10-26 13:05:04 +0200
committerChristian Mollekopf <chrigi_1@fastmail.fm>2017-10-26 13:05:04 +0200
commitecbd3b67e3f6e2bd3025b1fb9c734335612e554e (patch)
treef20b20dca3b6621834c167b870ac453f3bf9afc1
parent6db02b1f5b3d47578e1bc0a9bb7ca85da2fe2de8 (diff)
downloadsink-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.cpp33
-rw-r--r--examples/maildirresource/libmaildir/maildir.cpp3
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)
37struct MimeMessageReader { 37struct 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
82static Sink::ApplicationDomain::Mail::Contact getContact(const KMime::Headers::Generics::MailboxList *header) 91static 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'))