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 | |
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.
-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 |