Email::MIME::Kit v3

[email protected] (Ricardo Signes) Thu, 20 Nov 2014 21:45:48 -0500
Newsgroups perl.pep
Message-ID <[email protected]>
--azLHFNyN32YCQGCU
Content-Type: text/plain; charset=utf-8
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

Ever since its early releases, Email::MIME::Kit had a big problem.  It scre=
wed
up encodings.  Specifically, imagine his manifest (I'm kinda skipping some
required junk):

  # manifest.yaml
  renderer: TemplateToolkit
  headers:
    - Subject: "Message for [% name %]"
  alternatives:
    - type: text/plain
      path: body.txt
    - type: text/html
      path: body.html

The manifest turns into a data structure before it's used, and the subject
header is a text string that, later, will get encoded into MIME encoded-wor=
ds
on the assumption that it's all Unicode text.

The files on disk are read with :raw, then filled in as-is, and trusted to
already be UTF-8.

If your customer's name is =D0=A0=D0=B0=D1=81=D0=BF=D1=83=D1=82=D0=B8=D0=BD=
, strangely enough, you're okay.  The header
handling encodes it properly, and the wide characters (because Cyrillic
codepoints are all above U+00FF) turn into UTF-8 with a warning.  On the ot=
her
hand, for some trouble, consider =C3=86var Arnfj=C3=B6r=C3=B0 Bjarmason.  A=
ll those codepoints
are below U+0100, so the non-ASCII ones are encoded directly, and you end up
with =3DC6 (=C3=86) in your quoted-printable body instead of =3DC3=3D86 (=
=C3=86 UTF-8 encoded).

Now, you're probably actually okay.  Your email is not correct, but email
clients are good at dealing with your (read: my) stupid mistakes.  If your
email part says it's UTF-8 but it's actually Latin-1, mail clients will usu=
ally
do the right thing.

The big problem is when you've got both =C3=86var Arnfj=C3=B6r=C3=B0 Bjarma=
son and =D0=A0=D0=B0=D1=81=D0=BF=D1=83=D1=82=D0=B8=D0=BD
both in your email.  Your body is a mish mash of Latin-1 and UTF-8 data.

In Email::MIME::Kit v3, templates (or non-template bodies) loaded from disk=
 are
=E2=80=94 if and only if they're for text/* parts =E2=80=94 decoded into te=
xt and then, when
the email is assembled, it's encoded by Email::MIME's usual header_str
handling.

There's a case where this can start making things worse, rather than better.
If you know that templates in files are treated as bytes, you might be pass=
ing
in strings pre-encoded into UTF-8.  If that was the case, it will now become
mojibake.

Finally, plugins that read kit contents for uses as text will need upgradin=
g.
The only one I know of like this is my own
Email::MIME::Kit::Assembler::Markdown.  I will fix it.  The trick is: look =
at
what content-type is being built and consider using "get_decoded_kit_entry"
instead of "get_kit_entry."

I think this is an important change, and worth the breakage.  Please look at
your use of EMK and test with v3.

--=20
rjbs

--azLHFNyN32YCQGCU
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: Digital signature

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1

iQEcBAEBAgAGBQJUbqdcAAoJEOYby6cMccU5LscIALY+L/gcCMjw8xchWIrLvujx
UHZKnE1oPO2HYKEdWNlO+G7LMdEqYavu2kmebo1LabRofxQhwBE6T9kvQ5ixgyjg
7tXcq6arZIXFXHcaqNsetkHKcxzUQme8yAk1HQ1A3By3plVSwPdgApybkoFrGd9y
l5r+xU8g6gxkyImbuFg2WGrdkehmQt8NqmCIDQ74JSFgZXNLysL31151ClpGOfWT
fQv3YBygdah1+zWoX5CZFx5PkiOL6kNySadAhW+ce4BSpepUv3LSm3nY9clqYD9e
S708qto/mIjbZLImCI0blDjB5kIZxsPlh8Jj4JMeCQqiq/q08Eo6JdheQquiCic=
=5sLf
-----END PGP SIGNATURE-----

--azLHFNyN32YCQGCU--