diff options
author | Henare Degan <henare.degan@gmail.com> | 2013-03-07 18:16:16 +1100 |
---|---|---|
committer | Henare Degan <henare.degan@gmail.com> | 2013-03-07 18:16:16 +1100 |
commit | 2f6af09899e2822121d060db55fdd78b15f099db (patch) | |
tree | be85f2b518c82368a23573e799449067b83fef68 /lib/mail_handler | |
parent | c723b691a203563a6f059ffd088ad2d3d783cd13 (diff) |
Backport Mail's encoding code from 2.5 for Ruby 1.9
Decoding messages in Ruby 1.9 was screwing up but not dying like 1.8. Backporting this fixes the problem.
Diffstat (limited to 'lib/mail_handler')
-rw-r--r-- | lib/mail_handler/backends/mail_extensions.rb | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/lib/mail_handler/backends/mail_extensions.rb b/lib/mail_handler/backends/mail_extensions.rb index 34ced7319..611b44c4c 100644 --- a/lib/mail_handler/backends/mail_extensions.rb +++ b/lib/mail_handler/backends/mail_extensions.rb @@ -124,4 +124,49 @@ module Mail end end end + + # HACK: Backport encoding fixes for Ruby 1.9 from Mail 2.5 + # Can be removed when Rails relies on Mail > 2.5 + class Ruby19 + def Ruby19.b_value_decode(str) + match = str.match(/\=\?(.+)?\?[Bb]\?(.+)?\?\=/m) + if match + encoding = match[1] + str = Ruby19.decode_base64(match[2]) + str.force_encoding(fix_encoding(encoding)) + end + decoded = str.encode("utf-8", :invalid => :replace, :replace => "") + decoded.valid_encoding? ? decoded : decoded.encode("utf-16le", :invalid => :replace, :replace => "").encode("utf-8") + end + + def Ruby19.q_value_decode(str) + match = str.match(/\=\?(.+)?\?[Qq]\?(.+)?\?\=/m) + if match + encoding = match[1] + str = Encodings::QuotedPrintable.decode(match[2]) + str.force_encoding(fix_encoding(encoding)) + end + decoded = str.encode("utf-8", :invalid => :replace, :replace => "") + decoded.valid_encoding? ? decoded : decoded.encode("utf-16le", :invalid => :replace, :replace => "").encode("utf-8") + end + + # mails somtimes includes invalid encodings like iso885915 or utf8 so we transform them to iso885915 or utf8 + # TODO: add this as a test somewhere + # Encoding.list.map{|e| [e.to_s.upcase==fix_encoding(e.to_s.downcase.gsub("-", "")), e.to_s] }.select {|a,b| !b} + # Encoding.list.map{|e| [e.to_s==fix_encoding(e.to_s), e.to_s] }.select {|a,b| !b} + def Ruby19.fix_encoding(encoding) + case encoding + # ISO-8859-15, ISO-2022-JP and alike + when /iso-?(\d{4})-?(\w{1,2})/i then return "ISO-#{$1}-#{$2}" + # "ISO-2022-JP-KDDI" and alike + when /iso-?(\d{4})-?(\w{1,2})-?(\w*)/i then return "ISO-#{$1}-#{$2}-#{$3}" + # UTF-8, UTF-32BE and alike + when /utf-?(\d{1,2})?(\w{1,2})/i then return "UTF-#{$1}#{$2}" + # Windows-1252 and alike + when /Windows-?(.*)/i then return "Windows-#{$1}" + #more aliases to be added if needed + else return encoding + end + end + end end |