aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHenare Degan <henare.degan@gmail.com>2013-03-07 18:16:16 +1100
committerHenare Degan <henare.degan@gmail.com>2013-03-07 18:16:16 +1100
commit2f6af09899e2822121d060db55fdd78b15f099db (patch)
treebe85f2b518c82368a23573e799449067b83fef68
parentc723b691a203563a6f059ffd088ad2d3d783cd13 (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.rb45
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