Hello World
", "Simple paragraph"), ("Content
", "Heading + paragraph"), ("| A | B |
preformatted text\n line2", "Preformatted block", ), ("😃 emoji test", "Wide emoji"), ("link", "Anchor tag"), ( "
", "Blockquote with paragraph", ), ]; for (html, desc) in cases { let result = config::plain() .allow_width_overflow() .string_from_read(html.as_bytes(), 100); match result { Ok(output) => { println!("✓ Rendered ({}) =>\n{}", desc, output); } Err(e) => panic!("Unexpected error for {}: {:?}", desc, e), } } } /// Verifies that [`super::detach_and_store_attachments`] does not panic /// when mail-parser reports attachment offsets past the raw body length. /// /// Regression test for: "range end index X out of range for slice of /// length Y" panic caused by a malformed email whose attachment /// `raw_end_offset` exceeded the actual body size. #[tokio::test] async fn detach_attachments_bounds_check() { let raw = concat!( "From: sender@example.com\r\n", "To: recipient@example.com\r\n", "Subject: Test\r\n", "MIME-Version: 1.0\r\n", "Content-Type: multipart/mixed; boundary=\"bnd\"\r\n", "\r\n", "--bnd\r\n", "Content-Type: text/plain\r\n", "\r\n", "Hello\r\n", "--bnd\r\n", "Content-Type: application/octet-stream\r\n", "Content-Disposition: attachment; filename=\"test.bin\"\r\n", "\r\n", "AAAAABBBBBCCCCCDDDDDEEEEEAAAAABBBBBCCCCCDDDDDEEEEE\r\n", "--bnd--\r\n", ) .as_bytes() .to_vec(); let message = mail_parser::MessageParser::new() .parse(&raw) .expect("parse valid MIME message"); assert_eq!(message.attachment_count(), 1); // Truncate the raw body so the attachment's raw_end_offset lies // past the body end — exactly the scenario reported by users. let truncated = &raw[..raw.len() - 20]; assert!(truncated.len() < raw.len()); // Must not panic. let infos = super::detach_and_store_attachments( truncated, &message, "test_content_hash", 0, 0, ) .await; // The attachment count must still match so the consistency check // in reattach_eml_content doesn't fail later. assert_eq!(infos.len(), 1); } }Quoted text