summaryrefslogtreecommitdiffstats
path: root/common
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 /common
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.
Diffstat (limited to 'common')
-rw-r--r--common/mailpreprocessor.cpp33
1 files changed, 21 insertions, 12 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)