Browse Source

Fixes #3115 - Zammad can't import specific ISO-2022-JP mails

Mantas 4 years ago
parent
commit
66c0c4f513

+ 16 - 2
app/models/channel/email_parser.rb

@@ -512,13 +512,27 @@ process unprocessable_mails (tmp/unprocessable_mail/*.eml) again
   def force_single_part_encoding_if_needed(part)
     return if part.charset != 'iso-2022-jp'
 
-    part.body = part.body.encoded.unpack1('M').tr('_', ' ').force_encoding('ISO-2022-JP').encode('UTF-8')
+    part.body = part.body.encoded.unpack1('M').force_encoding('ISO-2022-JP').encode('UTF-8')
+  end
+
+  ISO2022JP_REGEXP = /=\?ISO-2022-JP\?B\?(.+?)\?=/.freeze
+
+  # https://github.com/zammad/zammad/issues/3115
+  def header_field_unpack_japanese(field)
+    field.value.gsub ISO2022JP_REGEXP do
+      Base64.decode64($1).force_encoding('SJIS').encode('UTF-8')
+    end
   end
 
   def message_header_hash(mail)
     imported_fields = mail.header.fields.map do |f|
       begin
-        value = f.to_utf8
+        value = if f.value.match?(ISO2022JP_REGEXP)
+                  header_field_unpack_japanese(f)
+                else
+                  f.to_utf8
+                end
+
         if value.blank?
           value = f.decoded.to_utf8
         end

+ 27 - 0
test/data/mail/mail091.yml

@@ -0,0 +1,27 @@
+--- !ruby/hash:ActiveSupport::HashWithIndifferentAccess
+from: '"岡本和正" <mail@domain.jp>'
+from_email: mail@domain.jp
+from_display_name: 岡本和正
+to: '"support@ourdomain.com" <support@ourdomain.com>'
+subject: メルマガ解除
+body: "<div>このアドレスへのメルマガを解除してください。</div>"
+content_type: text/html
+attachments:
+- !ruby/hash:ActiveSupport::HashWithIndifferentAccess
+  data: |
+    <html>
+    <head>
+    <meta http-equiv="Content-Type" content="text/html; charset=iso-2022-jp">
+    <style type="text/css" style="display:none;"> P {margin-top:0;margin-bottom:0;} </style>
+    </head>
+    <body dir="ltr">
+    <div style="font-family: Meiryo, メイリオ, &quot;Hiragino Sans&quot;, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
+    このアドレスへのメルマガを解除してください。</div>
+    </body>
+    </html>
+  filename: message.html
+  preferences: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
+    content-alternative: true
+    original-format: true
+    Mime-Type: text/html
+    Charset: iso-2022-jp

+ 28 - 0
test/data/mail/mail093.box

@@ -0,0 +1,28 @@
+Return-Path: <bar@example.org>
+Received: by example.com (Postfix, from userid 0)
+	id 123; Wed,  31 Jul 2020 11:38:04 +0900 (JST)
+To: =?ISO-2022-JP?B?iXeWa4z7IA==?= <foo@example.com>
+Subject: ƒc�[ƒ‹
+MIME-Version: 1.0
+Content-Type: multipart/alternative; boundary="--799140365efbe012d87669.81669397"
+Content-Transfer-Encoding: quoted-printable
+From: =?ISO-2022-JP?B?g2OBW4OLIEVYQU1QTEU=?= <bar@example.org>
+Message-Id: <123@example.org>
+Date: Wed,  31 Jul 2020 11:38:04 +0900 (JST)
+
+----799140365efbe012d87669.81669397
+Content-Type: text/html; charset=iso-2022-jp
+Content-Disposition: inline
+Content-Transfer-Encoding: quoted-printable
+
+<!DOCTYPE html>
+<html xmlns=3D"http://www.w3.org/1999/xhtml">
+<body>
+=1B$B!!:#$J$i!"=1B(B<span>=1B$B@hCe=1B(B100=1B$B;\@_8BDj=1B(B</span=
+>=1B$B$G=1B(B<br>=20
+=1B$B!!=1B(B<span>=1B$BL5NA%P!<%8%g%s=1B(B</span>=1B$B$rF3F~$$$?=
+$@$1$^$9!#=1B(B
+</body>
+</html>
+----799140365efbe012d87669.81669397--
+

+ 18 - 0
test/data/mail/mail093.yml

@@ -0,0 +1,18 @@
+--- !ruby/hash:ActiveSupport::HashWithIndifferentAccess
+from: ツール EXAMPLE <bar@example.org>
+from_email: bar@example.org
+from_display_name: ツール EXAMPLE
+to: 駅北口  <foo@example.com>
+subject: ツール
+body: 今なら、先着100施設限定で<br> 無料バージョンを導入いただけます。
+content_type: text/html
+attachments:
+- !ruby/hash:ActiveSupport::HashWithIndifferentAccess
+  data: "<!DOCTYPE html>\n<html xmlns=\"http://www.w3.org/1999/xhtml\">\n<body>\n 今なら、<span>先着100施設限定</span>で<br>
+    \n <span>無料バージョン</span>を導入いただけます。\n</body>\n</html>"
+  filename: message.html
+  preferences: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
+    content-alternative: true
+    original-format: true
+    Mime-Type: text/html
+    Charset: iso-2022-jp