emersion / go-message

✉️ A streaming Go library for the Internet Message Format and mail messages
MIT License
373 stars 108 forks source link

Fixes issue where nested multipart encoded boundaries are not parsed #162

Closed alexk307 closed 1 year ago

alexk307 commented 1 year ago

The bug occurs if a multipart encoded message is sent, and boundaries are nested within other boundaries. The parser will stop reading the message if the first boundary is closed, but this is not always the case.

Per the RFC:

The use of a media type of "multipart" in a body part within another
   "multipart" entity is explicitly allowed.  In such cases, for obvious
   reasons, care must be taken to ensure that each nested "multipart"
   entity uses a different boundary delimiter.  See [RFC 2049](https://www.rfc-editor.org/rfc/rfc2049) for an
   example of nested "multipart" entities.

Example message:

MIME-Version: 1.0

--xhRvHLcopjdFjxZ1sHUGhyfVnXPY7ls29V5P7Etdks. <----- first boundary
Content-Type: multipart/alternative;
 boundary="b2_xhRvHLcopjdFjxZ1sHUGhyfVnXPY7ls29V5P7Etdks". <------ defines a new boundary within the first

--b2_xhRvHLcopjdFjxZ1sHUGhyfVnXPY7ls29V5P7Etdks
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: quoted-printable

Hello World!

--b2_xhRvHLcopjdFjxZ1sHUGhyfVnXPY7ls29V5P7Etdks
Content-Type: multipart/related;
 boundary="xhRvHLcopjdFjxZ1sHUGhyfVnXPY7ls29V5P7Etdks";
 type="text/html"

--xhRvHLcopjdFjxZ1sHUGhyfVnXPY7ls29V5P7Etdks
Content-Type: text/html; charset=us-ascii
Content-Transfer-Encoding: quoted-printable

<html></html>

--xhRvHLcopjdFjxZ1sHUGhyfVnXPY7ls29V5P7Etdks
Content-Type: image/png; name=file.png
Content-Transfer-Encoding: base64
Content-ID: <something>
Content-Disposition: inline; filename=file.png

<b64'd png image>

--xhRvHLcopjdFjxZ1sHUGhyfVnXPY7ls29V5P7Etdks--  <------ This is the closing boundary, but since it occurs within the nested boundary, this means nothing and should be ignored. The parser will stop reading here.

--b2_xhRvHLcopjdFjxZ1sHUGhyfVnXPY7ls29V5P7Etdks--

--xhRvHLcopjdFjxZ1sHUGhyfVnXPY7ls29V5P7Etdks
Content-Type: ; name="somethingelse.html"
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="somethingelse.html"

<b64'd html file>

--xhRvHLcopjdFjxZ1sHUGhyfVnXPY7ls29V5P7Etdks--  <------ Actual end of the message/closing boundary