From 483931ea615d49a31d6de225f273e0945ad6cbb3 Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Fri, 6 May 2005 10:39:00 +0000 Subject: Fixed the TMail#body method to look at the content-transfer-encoding header and unquote the body according to the rules it specifies #1265 [Jamis Buck] Added unquoting even if the iconv lib can't be loaded--in that case, only the charset conversion is skipped #1265 [Jamis Buck] git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@1290 5ecf4fe2-1ee6-0310-87b1-e25e094e27de --- .../lib/action_mailer/vendor/tmail/quoting.rb | 170 +++++++++++---------- 1 file changed, 89 insertions(+), 81 deletions(-) (limited to 'actionmailer/lib/action_mailer/vendor/tmail') diff --git a/actionmailer/lib/action_mailer/vendor/tmail/quoting.rb b/actionmailer/lib/action_mailer/vendor/tmail/quoting.rb index 1ff00d9299..a31638100b 100644 --- a/actionmailer/lib/action_mailer/vendor/tmail/quoting.rb +++ b/actionmailer/lib/action_mailer/vendor/tmail/quoting.rb @@ -1,101 +1,109 @@ -begin - require 'iconv' - require 'base64' +require 'base64' - module TMail - class Mail - def subject(to_charset = 'utf-8') - Unquoter.unquote_and_convert_to(quoted_subject, to_charset) - end - - def unquoted_body(to_charset = 'utf-8') - from_charset = header['content-type']['charset'] rescue 'us-ascii' - Unquoter.unquote_and_convert_to(quoted_body, to_charset, from_charset) - end +module TMail + class Mail + def subject(to_charset = 'utf-8') + Unquoter.unquote_and_convert_to(quoted_subject, to_charset) + end - def body(to_charset = 'utf-8', &block) - attachment_presenter = block || Proc.new { |file_name| "Attachment: #{file_name}\n" } - - if multipart? - parts.collect { |part| - part.header["content-type"].main_type == "text" ? - part.unquoted_body(to_charset) : - attachment_presenter.call(part.header["content-type"].params["name"]) - }.join + def unquoted_body(to_charset = 'utf-8') + from_charset = header['content-type']['charset'] rescue 'us-ascii' + case (content_transfer_encoding || "7bit").downcase + when "quoted-printable" + Unquoter.unquote_quoted_printable_and_convert_to(quoted_body, + to_charset, from_charset) + when "base64" + Unquoter.unquote_base64_and_convert_to(quoted_body, to_charset, + from_charset) + when "7bit", "8bit" + Unquoter.convert_to(quoted_body, to_charset, from_charset) + when "binary" + quoted_body else - unquoted_body(to_charset) - end + quoted_body end end - class Unquoter - class << self - def unquote_and_convert_to(text, to_charset, from_charset = "iso-8859-1") - return "" if text.nil? - if text =~ /^=\?(.*?)\?(.)\?(.*)\?=$/ - from_charset = $1 - quoting_method = $2 - text = $3 - case quoting_method.upcase - when "Q" then - unquote_quoted_printable_and_convert_to(text, from_charset, to_charset) - when "B" then - unquote_base64_and_convert_to(text, from_charset, to_charset) - else - raise "unknown quoting method #{quoting_method.inspect}" - end - else - unquote_quoted_printable_and_convert_to(text, from_charset, to_charset) - end - end - - def unquote_quoted_printable_and_convert_to(text, from, to) - text ? Iconv.iconv(to, from || "ISO-8859-1", text.gsub(/_/," ").unpack("M*").first).first : "" - end - - def unquote_base64_and_convert_to(text, from, to) - text ? Iconv.iconv(to, from || "ISO-8859-1", Base64.decode64(text)).first : "" - end + def body(to_charset = 'utf-8', &block) + attachment_presenter = block || Proc.new { |file_name| "Attachment: #{file_name}\n" } + + if multipart? + parts.collect { |part| + part.header["content-type"].main_type == "text" ? + part.unquoted_body(to_charset) : + attachment_presenter.call(part.header["content-type"].params["name"]) + }.join + else + unquoted_body(to_charset) end end end - if __FILE__ == $0 - require 'test/unit' - - class TC_Unquoter < Test::Unit::TestCase - def test_unquote_quoted_printable - a ="=?ISO-8859-1?Q?[166417]_Bekr=E6ftelse_fra_Rejsefeber?=" - b = TMail::Unquoter.unquote_and_convert_to(a, 'utf-8') - assert_equal "[166417] Bekr\303\246ftelse fra Rejsefeber", b + class Unquoter + class << self + def unquote_and_convert_to(text, to_charset, from_charset = "iso-8859-1") + return "" if text.nil? + if text =~ /^=\?(.*?)\?(.)\?(.*)\?=$/ + from_charset = $1 + quoting_method = $2 + text = $3 + case quoting_method.upcase + when "Q" then + unquote_quoted_printable_and_convert_to(text, to_charset, from_charset) + when "B" then + unquote_base64_and_convert_to(text, to_charset, from_charset) + else + raise "unknown quoting method #{quoting_method.inspect}" + end + else + convert_to(text, to_charset, from_charset) + end end - def test_unquote_base64 - a ="=?ISO-8859-1?B?WzE2NjQxN10gQmVrcuZmdGVsc2UgZnJhIFJlanNlZmViZXI=?=" - b = TMail::Unquoter.unquote_and_convert_to(a, 'utf-8') - assert_equal "[166417] Bekr\303\246ftelse fra Rejsefeber", b + def unquote_quoted_printable_and_convert_to(text, to, from) + convert_to(text.gsub(/_/," ").unpack("M*").first, to, from) end - def test_unquote_without_charset - a ="[166417]_Bekr=E6ftelse_fra_Rejsefeber" - b = TMail::Unquoter.unquote_and_convert_to(a, 'utf-8') - assert_equal "[166417] Bekr\303\246ftelse fra Rejsefeber", b + def unquote_base64_and_convert_to(text, to, from) + convert_to(Base64.decode64(text), to, from) + end + + begin + require 'iconv' + def convert_to(text, to, from) + text ? Iconv.iconv(to, from || "ISO-8859-1", text).first : "" + end + rescue LoadError + # Not providing quoting support + def convert_to(text, to, from) + warn "Action Mailer: iconv not loaded; ignoring conversion from #{from} to #{to} (#{__FILE__}:#{__LINE__})" + text + end end end end -rescue LoadError => e - # Not providing quoting support - module TMail - class Mail - def subject - warn "Action Mailer: iconv couldn't be required, so the charset conversion is skipped" - quoted_subject - end - - def body - warn "Action Mailer: iconv couldn't be required, so the charset conversion is skipped" - quoted_body - end +end + +if __FILE__ == $0 + require 'test/unit' + + class TC_Unquoter < Test::Unit::TestCase + def test_unquote_quoted_printable + a ="=?ISO-8859-1?Q?[166417]_Bekr=E6ftelse_fra_Rejsefeber?=" + b = TMail::Unquoter.unquote_and_convert_to(a, 'utf-8') + assert_equal "[166417] Bekr\303\246ftelse fra Rejsefeber", b + end + + def test_unquote_base64 + a ="=?ISO-8859-1?B?WzE2NjQxN10gQmVrcuZmdGVsc2UgZnJhIFJlanNlZmViZXI=?=" + b = TMail::Unquoter.unquote_and_convert_to(a, 'utf-8') + assert_equal "[166417] Bekr\303\246ftelse fra Rejsefeber", b + end + + def test_unquote_without_charset + a ="[166417]_Bekr=E6ftelse_fra_Rejsefeber" + b = TMail::Unquoter.unquote_and_convert_to(a, 'utf-8') + assert_equal "[166417]_Bekr=E6ftelse_fra_Rejsefeber", b end end end -- cgit v1.2.3