warn about encoding errors; this requires Context

This commit is contained in:
B. Petersen
2020-12-04 12:25:45 +01:00
parent 0bdd1b7dc2
commit af045c245d

View File

@@ -688,7 +688,7 @@ impl MimeMessage {
let (mime_type, msg_type) = get_mime_type(mail)?;
let raw_mime = mail.ctype.mimetype.to_lowercase();
let filename = get_attachment_filename(mail)?;
let filename = get_attachment_filename(context, mail)?;
let old_part_count = self.parts.len();
@@ -1276,7 +1276,10 @@ fn is_attachment_disposition(mail: &mailparse::ParsedMail<'_>) -> bool {
/// returned. If Content-Disposition is "attachment" but filename is
/// not specified, filename is guessed. If Content-Disposition cannot
/// be parsed, returns an error.
fn get_attachment_filename(mail: &mailparse::ParsedMail) -> Result<Option<String>> {
fn get_attachment_filename(
context: &Context,
mail: &mailparse::ParsedMail,
) -> Result<Option<String>> {
let ct = mail.get_content_disposition();
// try to get file name as "encoded-words" from
@@ -1320,10 +1323,12 @@ fn get_attachment_filename(mail: &mailparse::ParsedMail) -> Result<Option<String
let (utf8_str, _, _) = charset.decode(&*decoded_bytes);
Some(utf8_str.into())
} else {
warn!(context, "latin1 encoding does not exist");
None
}
}
} else {
warn!(context, "apostroped encoding invalid");
None
}
}
@@ -1478,114 +1483,136 @@ mod tests {
assert!(is_attachment_disposition(&mail.subparts[1]));
}
fn load_mail_with_attachment(raw: &[u8]) -> ParsedMail {
fn load_mail_with_attachment<'a>(t: &'a TestContext, raw: &'a [u8]) -> ParsedMail<'a> {
let mail = mailparse::parse_mail(raw).unwrap();
assert!(get_attachment_filename(&mail).unwrap().is_none());
assert!(get_attachment_filename(&mail.subparts[0])
assert!(get_attachment_filename(&t.ctx, &mail).unwrap().is_none());
assert!(get_attachment_filename(&t.ctx, &mail.subparts[0])
.unwrap()
.is_none());
mail
}
#[test]
fn test_get_attachment_filename() {
let mail = load_mail_with_attachment(include_bytes!(
"../test-data/message/attach_filename_simple.eml"
));
let filename = get_attachment_filename(&mail.subparts[1]).unwrap();
#[async_std::test]
async fn test_get_attachment_filename() {
let t = TestContext::new().await;
let mail = load_mail_with_attachment(
&t,
include_bytes!("../test-data/message/attach_filename_simple.eml"),
);
let filename = get_attachment_filename(&t.ctx, &mail.subparts[1]).unwrap();
assert_eq!(filename, Some("test.html".to_string()))
}
#[test]
fn test_get_attachment_filename_encoded_words() {
let mail = load_mail_with_attachment(include_bytes!(
"../test-data/message/attach_filename_encoded_words.eml"
));
let filename = get_attachment_filename(&mail.subparts[1]).unwrap();
#[async_std::test]
async fn test_get_attachment_filename_encoded_words() {
let t = TestContext::new().await;
let mail = load_mail_with_attachment(
&t,
include_bytes!("../test-data/message/attach_filename_encoded_words.eml"),
);
let filename = get_attachment_filename(&t.ctx, &mail.subparts[1]).unwrap();
assert_eq!(filename, Some("Maßnahmen Okt. 2020.html".to_string()))
}
#[test]
fn test_get_attachment_filename_encoded_words_binary() {
let mail = load_mail_with_attachment(include_bytes!(
"../test-data/message/attach_filename_encoded_words_binary.eml"
));
let filename = get_attachment_filename(&mail.subparts[1]).unwrap();
#[async_std::test]
async fn test_get_attachment_filename_encoded_words_binary() {
let t = TestContext::new().await;
let mail = load_mail_with_attachment(
&t,
include_bytes!("../test-data/message/attach_filename_encoded_words_binary.eml"),
);
let filename = get_attachment_filename(&t.ctx, &mail.subparts[1]).unwrap();
assert_eq!(filename, Some(" § 165 Abs".to_string()))
}
#[test]
fn test_get_attachment_filename_encoded_words_windows1251() {
let mail = load_mail_with_attachment(include_bytes!(
"../test-data/message/attach_filename_encoded_words_windows1251.eml"
));
let filename = get_attachment_filename(&mail.subparts[1]).unwrap();
#[async_std::test]
async fn test_get_attachment_filename_encoded_words_windows1251() {
let t = TestContext::new().await;
let mail = load_mail_with_attachment(
&t,
include_bytes!("../test-data/message/attach_filename_encoded_words_windows1251.eml"),
);
let filename = get_attachment_filename(&t.ctx, &mail.subparts[1]).unwrap();
assert_eq!(filename, Some("file Что нового 2020.pdf".to_string()))
}
#[test]
fn test_get_attachment_filename_encoded_words_cont() {
#[async_std::test]
async fn test_get_attachment_filename_encoded_words_cont() {
// test continued encoded-words and also test apostropes work that way
let mail = load_mail_with_attachment(include_bytes!(
"../test-data/message/attach_filename_encoded_words_cont.eml"
));
let filename = get_attachment_filename(&mail.subparts[1]).unwrap();
let t = TestContext::new().await;
let mail = load_mail_with_attachment(
&t,
include_bytes!("../test-data/message/attach_filename_encoded_words_cont.eml"),
);
let filename = get_attachment_filename(&t.ctx, &mail.subparts[1]).unwrap();
assert_eq!(filename, Some("Maßn'ah'men Okt. 2020.html".to_string()))
}
#[test]
fn test_get_attachment_filename_encoded_words_bad_delimiter() {
let mail = load_mail_with_attachment(include_bytes!(
"../test-data/message/attach_filename_encoded_words_bad_delimiter.eml"
));
let filename = get_attachment_filename(&mail.subparts[1]).unwrap();
#[async_std::test]
async fn test_get_attachment_filename_encoded_words_bad_delimiter() {
let t = TestContext::new().await;
let mail = load_mail_with_attachment(
&t,
include_bytes!("../test-data/message/attach_filename_encoded_words_bad_delimiter.eml"),
);
let filename = get_attachment_filename(&t.ctx, &mail.subparts[1]).unwrap();
// not decoded as a space is missing after encoded-words part
assert_eq!(filename, Some("=?utf-8?q?foo?=.bar".to_string()))
}
#[test]
fn test_get_attachment_filename_apostrophed() {
let mail = load_mail_with_attachment(include_bytes!(
"../test-data/message/attach_filename_apostrophed.eml"
));
let filename = get_attachment_filename(&mail.subparts[1]).unwrap();
#[async_std::test]
async fn test_get_attachment_filename_apostrophed() {
let t = TestContext::new().await;
let mail = load_mail_with_attachment(
&t,
include_bytes!("../test-data/message/attach_filename_apostrophed.eml"),
);
let filename = get_attachment_filename(&t.ctx, &mail.subparts[1]).unwrap();
assert_eq!(filename, Some("Maßnahmen Okt. 2021.html".to_string()))
}
#[test]
fn test_get_attachment_filename_apostrophed_cont() {
let mail = load_mail_with_attachment(include_bytes!(
"../test-data/message/attach_filename_apostrophed_cont.eml"
));
let filename = get_attachment_filename(&mail.subparts[1]).unwrap();
#[async_std::test]
async fn test_get_attachment_filename_apostrophed_cont() {
let t = TestContext::new().await;
let mail = load_mail_with_attachment(
&t,
include_bytes!("../test-data/message/attach_filename_apostrophed_cont.eml"),
);
let filename = get_attachment_filename(&t.ctx, &mail.subparts[1]).unwrap();
assert_eq!(filename, Some("Maßnahmen März 2022.html".to_string()))
}
#[test]
fn test_get_attachment_filename_apostrophed_windows1251() {
let mail = load_mail_with_attachment(include_bytes!(
"../test-data/message/attach_filename_apostrophed_windows1251.eml"
));
let filename = get_attachment_filename(&mail.subparts[1]).unwrap();
#[async_std::test]
async fn test_get_attachment_filename_apostrophed_windows1251() {
let t = TestContext::new().await;
let mail = load_mail_with_attachment(
&t,
include_bytes!("../test-data/message/attach_filename_apostrophed_windows1251.eml"),
);
let filename = get_attachment_filename(&t.ctx, &mail.subparts[1]).unwrap();
assert_eq!(filename, Some("программирование.HTM".to_string()))
}
#[test]
fn test_get_attachment_filename_apostrophed_cp1252() {
let mail = load_mail_with_attachment(include_bytes!(
"../test-data/message/attach_filename_apostrophed_cp1252.eml"
));
let filename = get_attachment_filename(&mail.subparts[1]).unwrap();
#[async_std::test]
async fn test_get_attachment_filename_apostrophed_cp1252() {
let t = TestContext::new().await;
let mail = load_mail_with_attachment(
&t,
include_bytes!("../test-data/message/attach_filename_apostrophed_cp1252.eml"),
);
let filename = get_attachment_filename(&t.ctx, &mail.subparts[1]).unwrap();
assert_eq!(filename, Some("Auftragsbestätigung.pdf".to_string()))
}
#[test]
fn test_get_attachment_filename_combined() {
#[async_std::test]
async fn test_get_attachment_filename_combined() {
// test that if `filename` and `filename*0` are given, the filename is not doubled
let mail = load_mail_with_attachment(include_bytes!(
"../test-data/message/attach_filename_combined.eml"
));
let filename = get_attachment_filename(&mail.subparts[1]).unwrap();
let t = TestContext::new().await;
let mail = load_mail_with_attachment(
&t,
include_bytes!("../test-data/message/attach_filename_combined.eml"),
);
let filename = get_attachment_filename(&t.ctx, &mail.subparts[1]).unwrap();
assert_eq!(filename, Some("Maßnahmen Okt. 2020.html".to_string()))
}