You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
get_special_mailboxes per-account mode now also returns a <type>_path field
for each present special mailbox — the FULL mailbox path (drafts_path "[Gmail]/草稿") matching the mailbox field search_emails returns, so a
consumer can compare full-path == full-path directly instead of the #109
leaf-suffix heuristic. Built by an AppleScript container-walk that joins parent
mailbox names with / up to the account boundary (reproducing MailboxURL.mailboxPath); a top-level mailbox's path equals its leaf
(inbox_path "收件匣"). Purely additive — the leaf <type> field is unchanged,
and a walk failure omits only that _path key. The result tuple appends the 5
paths after the 5 leaf names, preserving the #179 fixed-tuple positions
([matchedId, matchedName, matchCount, n0…n4, p0…p4]). (#268)
to / cc / bcc accept RFC 5322 mailbox form (Name <email>) — recipients can display a person's name (#251). Previously the recipient parameters were documented as bare addresses; a Name <email> string happened to pass the boundary validation (single @) and flowed unparsed into AppleScript, while a legal name containing @ was mis-rejected by the same check. Now a new parseRecipient boundary parser splits the mailbox form; validation applies to the addr-spec part; the legacy AppleScript path emits native {name, address} recipient properties (Mail displays the person's name — this also silently benefits reply_email's cc_additional and forward_email's to, which share the fragment builder); and display-name recipients on compose_email / create_draft become a named mailto-ineligibility (the mailto URL carries addr-spec only per RFC 6068) — the same disclosed legacy-path trade-off as a custom from_address: names shown natively, body wrapped + disclosed; with require_wrapper_free: true, a clean refusal names the drop-the-names alternative. Bare-address calls are byte-identical. Contacts-based auto-naming stays a follow-up on the issue. Verify round (PR #262) hardened the parser: an unquoted name containing </> (e.g. the multi-angle Alice <a@x> <b@y>) is rejected at the boundary instead of silently reinterpreted as a send to the last address (RFC 5322 makes angles specials, forbidden in unquoted atoms; quoted names keep them), and the bare-angle form <a@b.c> normalizes to the bare address.
redirect_email recipient parity with #251 (#263). The shared boundary validation relaxed by #251 let Name <email> reach the redirect script builder, which passed the whole string as the AppleScript address (Mail's display-name fallback — no mis-send, but malformed-downstream). The builder now delegates to the shared name-aware recipientFragment: canonical (unpadded) bare addresses stay byte-identical (the #135 golden is untouched; a whitespace-padded bare address is now trimmed, matching validation and compose/reply/forward), mailbox-form recipients get the native {name, address} pair — compose/reply/forward/redirect now behave identically. Well-formed multi-angle inputs (two addr-specs, e.g. Alice <a@x> <b@y>) stay rejected at the shared boundary (#251 regression lock added for redirect); a malformed one-@ multi-angle input still passes the lite validator and lands as a Mail-level-invalid address (no mis-send) — shared-boundary hardening tracked as #265.
Fixed
Recipient parser hardening — malformed multi-angle rejection + quoted-pair decoding (#265, #266). The shared validateEmailAddresses boundary now rejects a recipient that parseRecipient could not cleanly split (name resolves to nil) yet still carries a matched <...> pair — the single-@ malformed multi-angle case (Alice <not-an-email> <bob@x>) that previously slipped the atCount check and landed whole in the AppleScript address. A clean bare addr-spec and the normalized bare-angle form (<a@b.c> → a@b.c) are unaffected; the pathological quoted-local-part literally containing a matched angle pair ("a<b>"@x) is explicitly unsupported. Separately, quoted display names now decode RFC 5322 quoted-pairs (\" → ", \\ → \) so the native recipient name carries the intended value rather than the backslash-escaped source form (#266). The parser uses a simple outer-quote heuristic (a name that both starts and ends with "), so a terminal escaped quote ("x\") is still classified as quoted and decoded; the decoded value is re-escaped for AppleScript backslash-first, so the emitted recipient literal is always balanced (no injection). A residual note: single-unmatched-angle malformed recipients (<a@x, a@x>) are not caught by the matched-pair boundary reject and land as Mail-level-invalid addresses (no mis-send) — tracked as #270.
Test isolation — awaited seam teardown (#267). The three RecipientDisplayNameTests seam-reset sites migrated from a detached defer { Task { … } } (which could reset the process-wide MailController.shared singleton after the next test started) to addTeardownBlock, which XCTest awaits.