summaryrefslogtreecommitdiff
path: root/config/initializers/mail_encoding_patch.rb
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-02-06 12:10:29 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2020-02-06 12:10:29 +0000
commit5564275a0b378298dc6281599cbfe71a937109ff (patch)
treea468e1e60046356410219c35c23a8a428c5e2c5e /config/initializers/mail_encoding_patch.rb
parentd87918510a866a5fcbbc2f899ad65c6938ebf5f5 (diff)
downloadgitlab-ce-5564275a0b378298dc6281599cbfe71a937109ff.tar.gz
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'config/initializers/mail_encoding_patch.rb')
-rw-r--r--config/initializers/mail_encoding_patch.rb82
1 files changed, 82 insertions, 0 deletions
diff --git a/config/initializers/mail_encoding_patch.rb b/config/initializers/mail_encoding_patch.rb
new file mode 100644
index 00000000000..d53b058ba75
--- /dev/null
+++ b/config/initializers/mail_encoding_patch.rb
@@ -0,0 +1,82 @@
+# Monkey patch mail 2.7.1 to fix quoted-printable issues with newlines
+# The issues upstream invalidate SMIME signatures under some conditions
+# This was working properly in 2.6.6
+#
+# See https://gitlab.com/gitlab-org/gitlab/issues/197386
+# See https://github.com/mikel/mail/issues/1190
+
+module Mail
+ module Encodings
+ # PATCH
+ # This reverts https://github.com/mikel/mail/pull/1113, which solves some
+ # encoding issues with binary attachments encoded in quoted-printable, but
+ # unfortunately breaks re-encoding of messages
+ class QuotedPrintable < SevenBit
+ def self.decode(str)
+ ::Mail::Utilities.to_lf str.gsub(/(?:=0D=0A|=0D|=0A)\r\n/, "\r\n").unpack1("M*")
+ end
+
+ def self.encode(str)
+ ::Mail::Utilities.to_crlf([::Mail::Utilities.to_lf(str)].pack("M"))
+ end
+ end
+ end
+
+ class Body
+ def encoded(transfer_encoding = nil, charset = nil)
+ # PATCH
+ # Use provided parameter charset (from parent Message) if not nil,
+ # otherwise use own self.charset
+ # Required because the Message potentially has on its headers the charset
+ # that needs to be used (e.g. 'Content-Type: text/plain; charset=UTF-8')
+ charset = self.charset if charset.nil?
+
+ if multipart?
+ self.sort_parts!
+ encoded_parts = parts.map { |p| p.encoded }
+ ([preamble] + encoded_parts).join(crlf_boundary) + end_boundary + epilogue.to_s
+ else
+ dec = Mail::Encodings.get_encoding(encoding)
+ enc = if Utilities.blank?(transfer_encoding)
+ dec
+ else
+ negotiate_best_encoding(transfer_encoding)
+ end
+
+ if dec.nil?
+ # Cannot decode, so skip normalization
+ raw_source
+ else
+ # Decode then encode to normalize and allow transforming
+ # from base64 to Q-P and vice versa
+ decoded = dec.decode(raw_source)
+
+ if defined?(Encoding) && charset && charset != "US-ASCII"
+ # PATCH
+ # We need to force the encoding: in the case of quoted-printable
+ # this will throw an exception otherwise, because `decoded` will have
+ # an encoding of BINARY (or its equivalent ASCII-8BIT),
+ # coming from QuotedPrintable#decode, and inside it from String#unpack1
+ decoded = decoded.force_encoding(charset)
+ decoded.force_encoding('BINARY') unless Encoding.find(charset).ascii_compatible?
+ end
+
+ enc.encode(decoded)
+ end
+ end
+ end
+ end
+
+ class Message
+ def encoded
+ ready_to_send!
+ buffer = header.encoded
+ buffer << "\r\n"
+ # PATCH
+ # Pass the Message charset down to the contained Body, the headers
+ # potentially contain the charset needed to be applied
+ buffer << body.encoded(content_transfer_encoding, charset)
+ buffer
+ end
+ end
+end