mikel / mail

A Really Ruby Mail Library
MIT License
3.6k stars 931 forks source link

Re-encoding a multipart message introduces extra newline characters #1576

Open dlouzan opened 1 year ago

dlouzan commented 1 year ago

Hello, this is a follow-up of https://github.com/mikel/mail/issues/1190#issuecomment-795904343.

Context: we are using the gem in GitLab, one of the use cases is S/MIME signing with an interceptor. The gem was recently updated to 2.8.1 in GitLab, so we gave this another try.

Sadly there's still some cases that introduce extra newlines when re-encoding an existing message object. Particularly, when using a multipart message. Below a repro case:

require 'mail'

email = Mail.new do
  to 'jane.doe@example.com'
  from 'John Dóe <john.doe@example.com>'
  subject 'Encoding tést'
end

text_part = Mail::Part.new do
  content_type 'text/plain; charset=UTF-8'
  content_transfer_encoding 'quoted-printable'
  body "\r\n\r\n@john.doe, now known as John Dóe has accepted your invitation to join the Administrator / htmltest project.\r\n\r\nhttp://169.254.169.254:3000/root/htmltest\r\n\r\n-- \r\nYou're receiving this email because of your account on 169.254.169.254.\r\n\r\n\r\n\r\n"
end

html_part = Mail::Part.new do
  content_type 'text/html; charset=UTF-8'
  content_transfer_encoding 'quoted-printable'
  body "\r\n\r\n@john.doe, now known as John Dóe has accepted your invitation to join the Administrator / htmltest project.\r\n\r\nhttp://169.254.169.254:3000/root/htmltest\r\n\r\n-- \r\nYou're receiving this email because of your account on 169.254.169.254.\r\n\r\n\r\n\r\n"
end

email.text_part = text_part
email.html_part = html_part

new_email = Mail.new(email)

new_email.encoded == email.encoded

This breaks S/MIME because the signature is calculated taking the original message, but when encoding the final message, it is modified by the new object, so the signature does not match.

We are currently monkey-patching the gem to fix the issue with this: https://gitlab.com/gitlab-org/gitlab/-/blob/master/config/initializers/mail_encoding_patch.rb.

You can also take a look at the test suite: https://gitlab.com/gitlab-org/gitlab/-/blob/master/spec/initializers/mail_encoding_patch_spec.rb

Thanks!

/cc @stanhu @jeremy