Skip to content

encoded headers may split characters across words #226

Description

@tisdall

The current email renderer uses quoted-printable encoding. Encoded-words very slightly from normal quoted-printable. One such difference is whether it's permissible to break a character's bytes between blocks. In quoted-printable, the decoding process involves removing the trailing =, concat the lines together, and then decode. With an encoded-word, each "word" is independent and a single character shouldn't span across multiple words.

The difference I'm describing is outlined in RFC 2047 §5(3):

The 'encoded-text' in an 'encoded-word' must be self-contained;
'encoded-text' MUST NOT be continued from one 'encoded-word' to
another.

...

Each 'encoded-word' MUST represent an integral number of characters.
A multi-octet character may not be split across adjacent 'encoded-
word's.

quoted-printable example (note that's an em-dash, not a hyphen):

Mail.Encoders.QuotedPrintable.encode(" –", 7)
|> IO.inspect()
|> Mail.Encoders.QuotedPrintable.decode()
|> IO.inspect()

Outputs " =E2=\r\n=80=93" and " –"

If using that same algorithm and example, the encoded words in a header could be =?UTF-8?Q?_=E2?= =?UTF-8?Q?=80=93?=. Some parsers are able to code that back into , but not all. Mail.Parsers.RFC2822.parse does parse it and Apple Mail does, but unfortunately I've hit a parser that requires all the bytes of a character be within a single encoded word (ie. =?UTF-8?Q?_=E2=80=93?=).

Code example:

Mail.build() 
|> Mail.put_subject("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx em-dash follows: – other text") 
|> Mail.render() 
|> IO.puts()

Outputs: Subject: =?UTF-8?Q?xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx em-dash follows: =E2?==?UTF-8?Q?=80=93 other text?=

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions