aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--actionmailer/CHANGELOG4
-rw-r--r--actionmailer/lib/action_mailer/vendor/tmail/quoting.rb33
-rw-r--r--actionmailer/test/fixtures/raw_email_with_partially_quoted_subject14
-rw-r--r--actionmailer/test/quoting_test.rb7
4 files changed, 42 insertions, 16 deletions
diff --git a/actionmailer/CHANGELOG b/actionmailer/CHANGELOG
index bac5eeafa5..85bf21d819 100644
--- a/actionmailer/CHANGELOG
+++ b/actionmailer/CHANGELOG
@@ -1,6 +1,8 @@
*SVN*
-* Make sure DOS newlines in quoted-printable text are normalized to unix newlines before unquoting. closes $166 and #4452. [Jamis Buck]
+* Make sure quoted-printable text is decoded correctly when only portions of the text are encoded. closes #3154. [jon@siliconcircus.com]
+
+* Make sure DOS newlines in quoted-printable text are normalized to unix newlines before unquoting. closes #4166 and #4452. [Jamis Buck]
* Fixed that iconv decoding should catch InvalidEncoding #3153 [jon@siliconcircus.com]
diff --git a/actionmailer/lib/action_mailer/vendor/tmail/quoting.rb b/actionmailer/lib/action_mailer/vendor/tmail/quoting.rb
index 8fbb6e55de..694242349d 100644
--- a/actionmailer/lib/action_mailer/vendor/tmail/quoting.rb
+++ b/actionmailer/lib/action_mailer/vendor/tmail/quoting.rb
@@ -49,20 +49,25 @@ module TMail
class << self
def unquote_and_convert_to(text, to_charset, from_charset = "iso-8859-1", preserve_underscores=false)
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, preserve_underscores)
- 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)
+ text.gsub(/(.*?)(?:(?:=\?(.*?)\?(.)\?(.*?)\?=)|$)/) do
+ before = $1
+ from_charset = $2
+ quoting_method = $3
+ text = $4
+
+ before = convert_to(before, to_charset, from_charset) if before.length > 0
+ before + case quoting_method
+ when "q", "Q" then
+ unquote_quoted_printable_and_convert_to(text, to_charset, from_charset, preserve_underscores)
+ when "b", "B" then
+ unquote_base64_and_convert_to(text, to_charset, from_charset)
+ when nil then
+ # will be nil at the end of the string, due to the nature of
+ # the regex used.
+ ""
+ else
+ raise "unknown quoting method #{quoting_method.inspect}"
+ end
end
end
diff --git a/actionmailer/test/fixtures/raw_email_with_partially_quoted_subject b/actionmailer/test/fixtures/raw_email_with_partially_quoted_subject
new file mode 100644
index 0000000000..e86108da1e
--- /dev/null
+++ b/actionmailer/test/fixtures/raw_email_with_partially_quoted_subject
@@ -0,0 +1,14 @@
+From jamis@37signals.com Mon May 2 16:07:05 2005
+Mime-Version: 1.0 (Apple Message framework v622)
+Content-Transfer-Encoding: base64
+Message-Id: <d3b8cf8e49f04480850c28713a1f473e@37signals.com>
+Content-Type: text/plain;
+ charset=EUC-KR;
+ format=flowed
+To: jamis@37signals.com
+From: Jamis Buck <jamis@37signals.com>
+Subject: Re: Test: =?UTF-8?B?Iua8ouWtlyI=?= mid =?UTF-8?B?Iua8ouWtlyI=?= tail
+Date: Mon, 2 May 2005 16:07:05 -0600
+
+tOu6zrrQwMcguLbC+bChwfa3ziwgv+y4rrTCIMfPs6q01MC7ILnPvcC0z7TZLg0KDQrBpiDAzLin
+wLogSmFtaXPA1LTPtNku
diff --git a/actionmailer/test/quoting_test.rb b/actionmailer/test/quoting_test.rb
index 41d4ab680b..77bd769be9 100644
--- a/actionmailer/test/quoting_test.rb
+++ b/actionmailer/test/quoting_test.rb
@@ -26,6 +26,11 @@ class QuotingTest < Test::Unit::TestCase
assert_match %r{Elapsed time}, mail.body
end
+ def test_email_with_partially_quoted_subject
+ mail = TMail::Mail.parse(IO.read("#{File.dirname(__FILE__)}/fixtures/raw_email_with_partially_quoted_subject"))
+ assert_equal "Re: Test: \"\346\274\242\345\255\227\" mid \"\346\274\242\345\255\227\" tail", mail.subject
+ end
+
private
# This whole thing *could* be much simpler, but I don't think Tempfile,
@@ -44,7 +49,7 @@ class QuotingTest < Test::Unit::TestCase
end
system("ruby #{test_name} > #{res_name}") or raise "could not run test in sandbox"
- File.read(res_name)
+ File.read(res_name).chomp
ensure
File.delete(test_name) rescue nil
File.delete(res_name) rescue nil