From 726297e5f8d84cbb434f9c4185f3cd1aaebe8e6e Mon Sep 17 00:00:00 2001
From: Aleksander Machniak <alec@alec.pl>
Date: Tue, 19 Feb 2013 10:56:02 -0500
Subject: [PATCH] Add workaround for invalid message charset detection by IMAP servers (#1488968)

---
 CHANGELOG                            |    3 ++-
 program/lib/Roundcube/rcube_imap.php |   30 +++++++++++++++++++++++-------
 program/steps/mail/func.inc          |    2 +-
 3 files changed, 26 insertions(+), 9 deletions(-)

diff --git a/CHANGELOG b/CHANGELOG
index 1ee72e9..cc83c6a 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,6 +1,7 @@
 CHANGELOG Roundcube Webmail
-===========================
+========================a===
 
+- Add workaround for invalid message charset detection by IMAP servers (#1488968)
 - Fix NUL characters in content-type of ms-tnef attachment (#1488964)
 - Fix regression in handling LDAP contact identifiers (#1488959)
 - Updated translations from Transifex
diff --git a/program/lib/Roundcube/rcube_imap.php b/program/lib/Roundcube/rcube_imap.php
index 74c1f53..18c6b12 100644
--- a/program/lib/Roundcube/rcube_imap.php
+++ b/program/lib/Roundcube/rcube_imap.php
@@ -1634,9 +1634,15 @@
         // Example of structure for malformed MIME message:
         // ("text" "plain" NIL NIL NIL "7bit" 2154 70 NIL NIL NIL)
         if ($headers->ctype && !is_array($structure[0]) && $headers->ctype != 'text/plain'
-            && strtolower($structure[0].'/'.$structure[1]) == 'text/plain') {
+            && strtolower($structure[0].'/'.$structure[1]) == 'text/plain'
+        ) {
+            // A special known case "Content-type: text" (#1488968)
+            if ($headers->ctype == 'text') {
+                $structure[1]   = 'plain';
+                $headers->ctype = 'text/plain';
+            }
             // we can handle single-part messages, by simple fix in structure (#1486898)
-            if (preg_match('/^(text|application)\/(.*)/', $headers->ctype, $m)) {
+            else if (preg_match('/^(text|application)\/(.*)/', $headers->ctype, $m)) {
                 $structure[0] = $m[1];
                 $structure[1] = $m[2];
             }
@@ -1660,11 +1666,21 @@
             $struct = $this->structure_part($structure, 0, '', $headers);
         }
 
-        // don't trust given content-type
-        if (empty($struct->parts) && !empty($headers->ctype)) {
-            $struct->mime_id = '1';
-            $struct->mimetype = strtolower($headers->ctype);
-            list($struct->ctype_primary, $struct->ctype_secondary) = explode('/', $struct->mimetype);
+        // some workarounds on simple messages...
+        if (empty($struct->parts)) {
+            // ...don't trust given content-type
+            if (!empty($headers->ctype)) {
+                $struct->mime_id  = '1';
+                $struct->mimetype = strtolower($headers->ctype);
+                list($struct->ctype_primary, $struct->ctype_secondary) = explode('/', $struct->mimetype);
+            }
+
+            // ...and charset (there's a case described in #1488968 where invalid content-type
+            // results in invalid charset in BODYSTRUCTURE)
+            if (!empty($headers->charset) && $headers->charset != $struct->ctype_parameters['charset']) {
+                $struct->charset                     = $headers->charset;
+                $struct->ctype_parameters['charset'] = $headers->charset;
+            }
         }
 
         $headers->structure = $struct;
diff --git a/program/steps/mail/func.inc b/program/steps/mail/func.inc
index 6b8879d..36ac1aa 100644
--- a/program/steps/mail/func.inc
+++ b/program/steps/mail/func.inc
@@ -1854,7 +1854,7 @@
             $filename = rcube_label('htmlmessage');
         }
         else {
-            $ext      = rcube_mime::get_mime_extensions($attachment->mimetype);
+            $ext      = (array) rcube_mime::get_mime_extensions($attachment->mimetype);
             $ext      = array_shift($ext);
             $filename = rcube_label('messagepart') . ' ' . $attachment->mime_id;
             if ($ext) {

--
Gitblit v1.9.1