Skip to content

Add UIDONLY and MESSAGELIMIT response parsing - #2

Draft
gabeosx wants to merge 18 commits into
rustmailer:mainfrom
gabeosx:codex/rustmailer-uidonly
Draft

Add UIDONLY and MESSAGELIMIT response parsing#2
gabeosx wants to merge 18 commits into
rustmailer:mainfrom
gabeosx:codex/rustmailer-uidonly

Conversation

@gabeosx

@gabeosx gabeosx commented Jul 29, 2026

Copy link
Copy Markdown

Summary

Add the parser types needed to use RFC 9586 UIDONLY safely:

  • represent UIDFETCH separately from ordinary sequence-number FETCH;
  • expose exact ENABLED UIDONLY confirmation through an opt-in parser;
  • parse UIDREQUIRED and MESSAGELIMIT response codes; and
  • reject zero and malformed UID/MESSAGELIMIT values.

The existing parse_response() behavior for ENABLED remains compatible.
Callers that need to distinguish successful ENABLE responses opt into
parse_response_with_enabled().

Why

After UIDONLY is enabled, the server sends UIDFETCH instead of ordinary FETCH.
Treating the leading UID as a mutable sequence number makes it impossible for
an async client or archiver to enforce the mode correctly.

This is the parser feature step for rustmailer/bichon#333. The same change is
also under discussion in djc#198.

Dependency

This draft is based on the fork update in #1. Until #1 merges, GitHub will also
show those parent-history commits in this PR; the UIDONLY feature itself is the
single commit 05439a90033d67297892c3fe206b8c4285df3821.

Verification

  • cargo fmt --all -- --check
  • cargo test --all-features: 103 passed
  • cargo clippy --all-targets -- -D warnings

The downstream async-imap PR pins this exact commit temporarily. That pin
should move to the accepted Rustmailer commit or release before downstream
merges.

Downstream PRs: rustmailer/async-imap#2 and rustmailer/bichon#334.

rustmailer and others added 18 commits April 21, 2026 09:27
Real-world IMAP servers (Dovecot, Cyrus) regularly emit 8-bit bytes in
BODYSTRUCTURE responses — typically MIME filenames in non-UTF-8
encodings like Latin-1 or ISO-8859-9 (e.g. Turkish "Görüntü1.png" from
Outlook). The strict 7-bit ASCII parser rejected these, breaking the
parse of a single bad mail and desyncing the entire bulk fetch
stream.

Two changes:

1. `is_char` now accepts any non-NUL byte instead of only US-ASCII.
   Real-world server behavior, and RFC 6855 / IMAP4rev2 (RFC 9051)
   formally allow UTF-8 in these positions.

2. The `*_utf8` parser functions (`string_utf8`, `nstring_utf8`,
   `astring_utf8`, `quoted_utf8`, `text`) now use
   `String::from_utf8_lossy` and return `Cow<'_, str>`, falling back
   to lossy decoding when bytes are not valid UTF-8 instead of
   failing the entire parse.

Callers that previously wrapped `&str` results in `Cow::Borrowed`
have been simplified to take the `Cow<'_, str>` directly. Tests
updated to match the new return types.

Adds a regression test (`test_body_structure_with_8bit_literal_filename`)
that reproduces the original failure: a BODYSTRUCTURE with
`("name" {8}\r\nGörüntü1)` (Turkish filename in Latin-1) now parses
successfully via lossy decoding.
Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 6 to 7.
- [Release notes](https://github.com/codecov/codecov-action/releases)
- [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md)
- [Commits](codecov/codecov-action@v6...v7)

---
updated-dependencies:
- dependency-name: codecov/codecov-action
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps [actions/checkout](https://github.com/actions/checkout) from 6 to 7.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](actions/checkout@v6...v7)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants