thunderbird / thunderbird/thunderbird-android
Message Reader - Add support for Inline image when `Content-Type: multipart/mixed` and no `Content-ID` header is present
@rafaeltonholo is already working on this.
Since Jun 22, 2026.
- Dominant language
- Kotlin
- Stars
- 14k
- Forks
- 2.8k
- Avg merge
- 3d 3h
- Merged PRs (30d)
- 57
Description
🎯 The objective
Some email clients, like Apple Mail, occasionally send emails with a Content-Type: multipart/mixed. In these cases, an inline image is included in the message body without an HTML tag or a Content-ID header.
This creates an issue in TfA, where the image is displayed only as an attachment rather than being inlined, leading to incorrect and unusual rendering of the message body.
Currently, TfA only supports inline images that have a Content-ID header and are included within an HTML <img /> tag.
The goal of this milestone is to enhance support for inline images, aligning our feature set with that of Thunderbird for Desktop.
🎒 Resources
Thunderbird for Desktop
Thanks, @maxemig, for providing these resources.
Thunderbird libmime multipart subtypes (dispatch: mailnews/mime/src/mimei.cpp#573-642; all derive from base MimeMultipart in mimemult.cpp).
- multipart/mixed (
mimemmix.cpp): the baseline. Parts shown sequentially in order; any part with a provided filename is also listed as an attachment. Unknown subtypes fall back to this. - multipart/related (
mimemrel.cpp): one "head" part (the HTML body); the rest are NOT shown as separate parts but registered byContent-ID/Content-Locationforcid: rewriting into the body. Overridesoutput_child_p. Orphan part with noCID/Content-Location-> output as a normal attachment instead of being dropped.
Implementation notes:
- Inline render -
mimei.cpp#mime_create(): image/png -> mimeInlineImageClass, CD "inline" keeps the class; images are even exempt from the attachment demotion block. - Attachment listing -
mimemoz2.cpp#NotifyEmittersOfAttachmentList(): an inline, displayable part is hidden ONLY if it has no provided filename. A filename (CD filename= or CT name=) setsm_realName/m_hasFilename, so the skip gate is not taken, and it is listed.
Gate = presence of a provided filename (m_hasFilename), set at:
https://searchfox.org/comm-central/source/mailnews/mime/src/mimemoz2.cpp#434-448
Thunderbird for Android
- A message is defined by
Viewable`s - The
Viewables are built byMessageExtractor#findViewablesAndAttachments()method, where we separate theViewableand theAttachmentsfrom the messageParts AttachmentViewInfodefines the attachment metadata and state informationMimeTypeUtil#isSupportedImageType(String mimeType)defines what a supported image is used onAttachmentViewInfoAttachmentResolver#buildCidToAttachmentUriMap()resolves an image via it's cid.
🦮 Rules of the Road
🟢 In Scope
- Create an RFC for the given feature
- Create a Technical Design for the given feature
- Implementation TBD.
🔴 Out of Scope
- TBD
🚧 Technical and/or Business Requirements
- TBD
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.