emersion / emersion/go-message

Inline vs Attachment part logic is insufficient for emails in the wild

Open
#138 5 comments 2 reactions 0 assignees View on GitHub
Dominant language
Go
Stars
458
Forks
129
PR merge metrics
No merged PRs in 30d

Description

Hello,

with the current implementation, interface `PartHeader` is [implemented](https://github.com/emersion/go-message/blob/87d83aac2f695c202fbb6acc422e3f04b27a9f96/mail/reader.go#L104) as either `InlineHeader` or `AttachmentHeader` that both embed `message.Header`. ~~And although it's not documented by the package, the [wiki example](https://github.com/emersion/go-imap/wiki/Fetching-messages) implies that `PartHeader` will always be one of the two.~~

The logic to decide whether its `AttachmentHeader` or `PartHeader`,
```golang
if disp == "inline" || (disp != "attachment" && strings.HasPrefix(t, "text/")) {
mp.Header = &InlineHeader{p.Header}
} else {
mp.Header = &AttachmentHeader{p.Header}
}
```
unfortunately, doesn't always work for emails in the wild. E.g., I have a message with the following part header:
```
Content-Type: text/plain; name="emailreceipt_20121015R2315576090.pdf"
Content-Disposition: inline; filename=emailreceipt_20121015R2315576090.pdf

%PDF-1.4..%...
```
It's clearly a PDF attachment, but is currently classified as `InlineHeader`, so we cannot use `AttachmentHeader.Filename` to extract the filename.

To solve this problem, the user code can of course cast `PartHeader` as `Header` (which will succeed with the current implementation), and then effectively re-implement `AttachmentHeader.Filename` logic by perusing `Header.ContentDisposition` and `Header.ContentType` methods.

The alternative would be, at a minimum, to extend `PartHeader` interface to directly expose `ContentDisposition` and `ContentType`, which will help the user code that works with malformed parts. (If this indeed a desired direction, I'm happy to create a pull request).

Another alternative would be to improve the Inline vs Attachment logic, but it will probably be brittle as you cannot enumerate badness in the wild.

Thoughts?

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.