diff --git a/python/tests/test_account.py b/python/tests/test_account.py index 0a177f570..0d3c15a41 100644 --- a/python/tests/test_account.py +++ b/python/tests/test_account.py @@ -477,6 +477,30 @@ class TestOnlineAccount: assert msg2.filename.endswith("html.zip") assert msg.filename != msg2.filename + def test_send_file_html_attachment(self, tmpdir, acfactory, lp): + ac1, ac2 = acfactory.get_two_online_accounts() + chat = self.get_chat(ac1, ac2) + + basename = "test.html" + content = "textdata" + + p = os.path.join(tmpdir.strpath, basename) + with open(p, "w") as f: + # write wrong html to see if core tries to parse it + # (it shouldn't as it's a file attachment) + f.write(content) + + lp.sec("ac1: prepare and send attachment + text to ac2") + chat.send_file(p, mime_type="text/html") + + lp.sec("ac2: receive message") + ev = ac2._evlogger.get_matching("DC_EVENT_INCOMING_MSG|DC_EVENT_MSGS_CHANGED") + assert ev[2] > const.DC_CHAT_ID_LAST_SPECIAL + msg = ac2.get_message_by_id(ev[2]) + + assert open(msg.filename).read() == content + assert msg.filename.endswith(basename) + def test_mvbox_sentbox_threads(self, acfactory, lp): lp.sec("ac1: start with mvbox thread") ac1 = acfactory.get_online_configuring_account(mvbox=True, sentbox=True) diff --git a/src/mimeparser.rs b/src/mimeparser.rs index 436933bba..8e5df288a 100644 --- a/src/mimeparser.rs +++ b/src/mimeparser.rs @@ -509,11 +509,22 @@ impl<'a> MimeParser<'a> { let (mime_type, msg_type) = get_mime_type(mail)?; let raw_mime = mail.ctype.mimetype.to_lowercase(); + info!( + self.context, + "add_single_part_if_known {:?} {:?}", mime_type, msg_type + ); + let old_part_count = self.parts.len(); + let is_attachment = mail + .get_content_disposition()? + .params + .iter() + .any(|(key, _value)| key.starts_with("filename")); + // regard `Content-Transfer-Encoding:` match mime_type.type_() { - mime::TEXT | mime::HTML => { + mime::TEXT | mime::HTML if !is_attachment => { let decoded_data = match mail.get_body() { Ok(decoded_data) => decoded_data, Err(err) => { @@ -547,7 +558,12 @@ impl<'a> MimeParser<'a> { self.is_forwarded = true; } } - mime::IMAGE | mime::AUDIO | mime::VIDEO | mime::APPLICATION => { + mime::TEXT + | mime::HTML + | mime::IMAGE + | mime::AUDIO + | mime::VIDEO + | mime::APPLICATION => { // try to get file name from // `Content-Disposition: ... filename*=...` // or `Content-Disposition: ... filename*0*=... filename*1*=... filename*2*=...`