The reader walks the MIME tree with its container context: alternative picks versions, related finds its root by start, attached multiparts stay whole, digest children are messages. Nesting deeper than 64 levels, counting enclosed messages, is refused, and over-deep parse results are taken apart iteratively so dropping them cannot overflow the stack. Composite parts with a Content-ID are cid targets. The writer keeps attachment parameters and Content-IDs, writes multipart and message attachments unencoded, and makes its own Message-ID. SMTP adds BODY=8BITMIME for 8-bit bodies and SMTPUTF8 when any header block at any depth is 8-bit. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
5.9 KiB
FAIL
-
crates/ely-mail-engine/src/mime/walk.rs:43 — [P1] Unbounded MIME traversal can abort the application. A valid 138,017-byte message containing 2,048 nested multipart/mixed containers parses into 2,049 parts successfully, but
readthen overflows the stack and terminates the Windows test process with0xc00000fd. This is a process abort, not a recoverableError::Mime, and the mail engine runs inside the application. Replace recursive traversal with an explicit stack, or enforce a checked nesting limit that returns an error before exhausting the stack. Add a regression covering deeply nested input. Reproduced in.work/C12.2-r2/depth.log; the existing 46-test mail-engine suite passes. -
Cargo.toml:62 — [P2] The mail-parser dependency omits
full_encoding, whose default is disabled. Its multibyte charset decoders consequently use lossy UTF-8 conversion. A validSubject: =?GB2312?B?1tDOxA==?=and a text/plain body declaringcharset=gb2312with base641tDOxA==both read as four replacement characters instead of中文, without a decoding warning. Enable the dependency's charset support and test multibyte encoded headers and bodies. The same isolated probe passes when onlymail-parser/full_encodingis enabled; see.work/C12.2-r2/encoding-before.logandencoding-feature.log. -
crates/ely-mail-engine/src/mime/walk.rs:133 — [P2] Preserving text attachment octets now loses the charset needed to interpret those octets.
leafdiscards all Content-Type parameters. Reading atext/plain; charset=iso-8859-1attachment containingCaf=E9, copying its returnedPartintoDraft.attachments, and building it emitsContent-Type: text/plainwith the Latin-1 bytes unchanged. Parsing the forwarded attachment yieldsCaf�. Without the charset, the declared default is US-ASCII (RFC 2046 §4.1.2). Preserve and serialize the parameters required to interpret attachment bytes, and test the recipient's decoded attachment text after forwarding. The existing byte-equality regression cannot detect this loss. Reproduced in.work/C12.2-r2/probes.log. -
crates/ely-mail-engine/src/mime.rs:159 — [P2] Multipart attachments returned by
readcannot be forwarded as valid MIME. Theirbytesinclude the entity headers, butbuildtreats those bytes as a binary leaf: an attached multipart/alternative becomesContent-Type: multipart/alternativewithout a boundary, followed by a base64 encoding of its original headers and body. The recipient parser sees a binary leaf instead of the original multipart structure. Base64 transfer encoding is prohibited on multipart entities (RFC 2045 §6.4). Serialize these attachments as complete MIME entities with their boundary and children and a permitted transfer encoding. Add a read/build/parse regression for the attached multipart covered by round 1. Reproduced in.work/C12.2-r2/probes.log. -
crates/ely-mail-engine/src/mime/walk.rs:104 — [P2] The round 1 related-disposition fix still excludes the related root. A multipart/related with
type="text/html"whose first child is text/html withContent-Disposition: attachment; filename=body.htmlreturnshtml: Noneand treats the root as an attachment, becauserelatedsends it throughbody's attachment guard. Related processing must ignore the disposition type for the root as well as its sibling resources (RFC 2387 §4). Carry that container context into root selection, while preserving the rules for the root's descendants, and add this root-disposition regression. Reproduced in.work/C12.2-r2/related.log. -
crates/ely-mail-engine/src/mime/walk.rs:114 — [P2] A multipart related resource loses its own entity, Content-ID and filename. With an HTML root and a sibling multipart/alternative carrying
Content-ID: <entity@example.com>andfilename=entity.mime,resourcerecursively flattens the sibling before inspecting its metadata. The result has no inline target forentity@example.com; only an unnamed text/plain descendant remains in attachments. The compound resource can neither be resolved by its CID nor saved with its original contents. Related processing must retain the correspondence between an entity, its headers and its Content-ID (RFC 2387 §6.1). Preserve the resource entity and metadata when traversing composite resources, and add this regression. Reproduced in.work/C12.2-r2/related.log. -
crates/ely-mail-engine/src/mime/walk.rs:45 — [P2] The claimed non-related CID handling is bypassed for text/plain and text/html parts. In multipart/mixed, a plain body followed by a text/html resource with
Content-ID: <frame@example.com>and inline disposition returns that resource asMail.html, with an emptyinlinelist. Its Content-ID and original part bytes are unavailable to callers, so a CID link to it cannot be resolved. This contradicts C12.2's explicit claim that non-attachment CID parts outside related containers become CID targets. Classify text resources using their container context before consuming them as body strings, and test text CID targets as well as binary images. Reproduced in.work/C12.2-r2/related.log. -
crates/ely-mail-engine/src/mime/walk.rs:170 — [P2] Unrecognized disposition types are silently treated as inline body text. A multipart/mixed containing plain
bodyfollowed by text/plain withContent-Disposition: x-file; filename=file.txtandprivate attachmentreads astext: Some("body\nprivate attachment")with zero attachments. Unrecognized disposition types should be handled as attachments, retaining their filename (RFC 2183 §2.8). Apply that classification outside the related-container override and add an unknown-disposition regression. Reproduced in.work/C12.2-r2/probes.log.