Finding (High). extract_mail_parts pushes the parent part after recursing (post-order, mail_parser.rs:86), so multipart/* container nodes and body parts all land in attachments with an empty filename (mail_parser.rs:49–57). A one-image email yields 4 entries; test_attachments.py:6 asserts len == 4, encoding the bug as expected behavior.
Fix. Classify by a real filename via Content-Disposition: attachment then Content-Type; name=; do not push multipart containers; do not call get_body_raw() on containers (it re-includes children's bytes). See sketch in the audit.
Acceptance
⚠️ Breaking change — requires a minor version bump. See Open Question on whether current shape is relied upon.
Audit ref: M2-T1. Related: #DISPOSITION.
Finding (High).
extract_mail_partspushes the parent part after recursing (post-order,mail_parser.rs:86), somultipart/*container nodes and body parts all land inattachmentswith an empty filename (mail_parser.rs:49–57). A one-image email yields 4 entries;test_attachments.py:6assertslen == 4, encoding the bug as expected behavior.Fix. Classify by a real filename via
Content-Disposition: attachmentthenContent-Type; name=; do not push multipart containers; do not callget_body_raw()on containers (it re-includes children's bytes). See sketch in the audit.Acceptance
len(attachment_mail.attachments) == 1for the single-attachment fixtureattachments[0].filenameis populated.pyistub and README reflect the corrected semanticsAudit ref: M2-T1. Related: #DISPOSITION.