diff --git a/crates/mailparsing/src/mimepart.rs b/crates/mailparsing/src/mimepart.rs index b560ca81..db631b45 100644 --- a/crates/mailparsing/src/mimepart.rs +++ b/crates/mailparsing/src/mimepart.rs @@ -308,12 +308,11 @@ impl<'a> MimePart<'a> { } }; - let (decoded, _malformed) = info.charset.decode_without_bom_handling(&bytes); - if info.is_text { + let (decoded, _malformed) = info.charset.decode_without_bom_handling(&bytes); Ok(DecodedBody::Text(decoded.to_string().into())) } else { - Ok(DecodedBody::Binary(decoded.as_bytes().to_vec())) + Ok(DecodedBody::Binary(bytes)) } } @@ -1273,4 +1272,19 @@ Ok( .conformance() .contains(MessageConformance::MISSING_COLON_VALUE)); } + + /// This is a regression test for an issue where we'd interpret the + /// binary bytes as default windows-1252 codepage charset, and mangle them. + /// The high byte is sufficient to trigger the offending code prior + /// to the fix + #[test] + fn rebuild_binary() { + let expect = &[0, 1, 2, 3, 0xbe, 4, 5]; + let part = MimePart::new_binary("applicat/octet-stream", expect, None); + + let rebuilt = part.rebuild().unwrap(); + let body = rebuilt.body().unwrap(); + + assert_eq!(body, DecodedBody::Binary(expect.to_vec())); + } } diff --git a/docs/changelog/main.md b/docs/changelog/main.md index a762de85..4e508b22 100644 --- a/docs/changelog/main.md +++ b/docs/changelog/main.md @@ -100,3 +100,6 @@ [msg:get_meta](../reference/message/get_meta.md) and [msg:set_meta](../reference/message/set_meta.md) now internally will ensure that the data or meta portion of the message is loaded from spool. +* Rebuilding a MIME message (such as via `msg:check_fix_conformance`) that had + binary attachments would incorrectly re-interpret the bytes as windows-1252 + encoded characters, damaging the attachment.