From 5579ef662197029afbf90d7bc2bfb5ba594475ac Mon Sep 17 00:00:00 2001
From: Aleksander Machniak <alec@alec.pl>
Date: Thu, 17 Dec 2015 03:29:30 -0500
Subject: [PATCH] Fix handling of message/rfc822 attachments on replies and forwards (#1490607)

---
 program/steps/mail/func.inc |  143 +++++++++++++++++++++++++++--------------------
 1 files changed, 81 insertions(+), 62 deletions(-)

diff --git a/program/steps/mail/func.inc b/program/steps/mail/func.inc
index 072ee71..3eee82d 100644
--- a/program/steps/mail/func.inc
+++ b/program/steps/mail/func.inc
@@ -23,40 +23,8 @@
 // always instantiate storage object (but not connect to server yet)
 $RCMAIL->storage_init();
 
-// set imap properties and session vars
-if (strlen(trim($mbox = rcube_utils::get_input_value('_mbox', rcube_utils::INPUT_GPC, true)))) {
-    $RCMAIL->storage->set_folder(($_SESSION['mbox'] = $mbox));
-}
-else if ($RCMAIL->storage) {
-    $_SESSION['mbox'] = $RCMAIL->storage->get_folder();
-}
-
-if (!empty($_GET['_page'])) {
-    $RCMAIL->storage->set_page(($_SESSION['page'] = intval($_GET['_page'])));
-}
-
-$a_threading        = $RCMAIL->config->get('message_threading', array());
-$message_sort_col   = $RCMAIL->config->get('message_sort_col');
-$message_sort_order = $RCMAIL->config->get('message_sort_order');
-
-// set default sort col/order to session
-if (!isset($_SESSION['sort_col'])) {
-    $_SESSION['sort_col'] = $message_sort_col ? $message_sort_col : '';
-}
-if (!isset($_SESSION['sort_order'])) {
-  $_SESSION['sort_order'] = strtoupper($message_sort_order) == 'ASC' ? 'ASC' : 'DESC';
-}
-
-// set threads mode
-if (isset($_GET['_threads'])) {
-    if ($_GET['_threads'])
-        $a_threading[$_SESSION['mbox']] = true;
-    else
-        unset($a_threading[$_SESSION['mbox']]);
-
-    $RCMAIL->user->save_prefs(array('message_threading' => $a_threading));
-}
-$RCMAIL->storage->set_threading($a_threading[$_SESSION['mbox']]);
+// init environment - set current folder, page, list mode
+rcmail_init_env();
 
 // set message set for search result
 if (!empty($_REQUEST['_search']) && isset($_SESSION['search'])
@@ -66,6 +34,10 @@
 
     $OUTPUT->set_env('search_request', $_REQUEST['_search']);
     $OUTPUT->set_env('search_text', $_SESSION['last_text_search']);
+}
+
+if (!empty($_SESSION['browser_caps']) && !$OUTPUT->ajax_call) {
+    $OUTPUT->set_env('browser_capabilities', $_SESSION['browser_caps']);
 }
 
 // set main env variables, labels and page title
@@ -115,11 +87,7 @@
 
     // set configuration
     $RCMAIL->set_env_config(array('delete_junk', 'flag_for_deletion', 'read_when_deleted',
-        'skip_deleted', 'display_next', 'message_extwin', 'compose_extwin', 'forward_attachment'));
-
-    if (!empty($_SESSION['browser_caps'])) {
-        $OUTPUT->set_env('browser_capabilities', $_SESSION['browser_caps']);
-    }
+        'skip_deleted', 'display_next', 'message_extwin', 'forward_attachment'));
 
     if (!$OUTPUT->ajax_call) {
         $OUTPUT->add_label('checkingmail', 'deletemessage', 'movemessagetotrash',
@@ -127,7 +95,7 @@
             'copy', 'move', 'quota', 'replyall', 'replylist');
     }
 
-    $pagetitle = $RCMAIL->localize_foldername($RCMAIL->storage->mod_folder($mbox_name), true);
+    $pagetitle = $RCMAIL->localize_foldername($mbox_name, true);
     $pagetitle = str_replace($delimiter, " \xC2\xBB ", $pagetitle);
 
     $OUTPUT->set_pagetitle($pagetitle);
@@ -166,6 +134,64 @@
 ));
 
 
+
+/**
+ * Sets storage properties and session
+ */
+function rcmail_init_env()
+{
+    global $RCMAIL;
+
+    $default_threading  = $RCMAIL->config->get('default_list_mode', 'list') == 'threads';
+    $a_threading        = $RCMAIL->config->get('message_threading', array());
+    $message_sort_col   = $RCMAIL->config->get('message_sort_col');
+    $message_sort_order = $RCMAIL->config->get('message_sort_order');
+
+    // set imap properties and session vars
+    if (!strlen($mbox = rcube_utils::get_input_value('_mbox', rcube_utils::INPUT_GPC, true))) {
+        $mbox = strlen($_SESSION['mbox']) ? $_SESSION['mbox'] : 'INBOX';
+    }
+    if (!($page = intval($_GET['_page']))) {
+        $page = $_SESSION['page'] ? $_SESSION['page'] : 1;
+    }
+
+    $RCMAIL->storage->set_folder($_SESSION['mbox'] = $mbox);
+    $RCMAIL->storage->set_page($_SESSION['page'] = $page);
+
+    // set default sort col/order to session
+    if (!isset($_SESSION['sort_col'])) {
+        $_SESSION['sort_col'] = $message_sort_col ? $message_sort_col : '';
+    }
+    if (!isset($_SESSION['sort_order'])) {
+        $_SESSION['sort_order'] = strtoupper($message_sort_order) == 'ASC' ? 'ASC' : 'DESC';
+    }
+
+    // set threads mode
+    if (isset($_GET['_threads'])) {
+        if ($_GET['_threads']) {
+            // re-set current page number when listing mode changes
+            if (!$a_threading[$_SESSION['mbox']]) {
+                $RCMAIL->storage->set_page($_SESSION['page'] = 1);
+            }
+
+            $a_threading[$_SESSION['mbox']] = true;
+        }
+        else {
+            // re-set current page number when listing mode changes
+            if ($a_threading[$_SESSION['mbox']]) {
+                $RCMAIL->storage->set_page($_SESSION['page'] = 1);
+            }
+
+            $a_threading[$_SESSION['mbox']] = false;
+        }
+
+        $RCMAIL->user->save_prefs(array('message_threading' => $a_threading));
+    }
+
+    $threading = isset($a_threading[$_SESSION['mbox']]) ? $a_threading[$_SESSION['mbox']] : $default_threading;
+
+    $RCMAIL->storage->set_threading($threading);
+}
 
 /**
  * Returns default search mods
@@ -761,8 +787,8 @@
  * Convert the given message part to proper HTML
  * which can be displayed the message view
  *
- * @param object rcube_message_part Message part
- * @param array  Display parameters array 
+ * @param rcube_message_part Message part
+ * @param array              Display parameters array
  * @return string Formatted HTML string
  */
 function rcmail_print_body($part, $p = array())
@@ -797,7 +823,7 @@
     }
     else {
         // assert plaintext
-        $body = $part->body;
+        $body = $data['body'];
         $part->ctype_secondary = $data['type'] = 'plain';
     }
 
@@ -1161,7 +1187,7 @@
                 else if (!rcube_utils::mem_check($part->size * 10)) {
                     $out .= html::span('part-notice', $RCMAIL->gettext('messagetoobig'). ' '
                         . html::a('?_task=mail&_action=get&_download=1&_uid='.$MESSAGE->uid.'&_part='.$part->mime_id
-                            .'&_mbox='. urlencode($RCMAIL->storage->get_folder()), $RCMAIL->gettext('download')));
+                            .'&_mbox='. urlencode($MESSAGE->folder), $RCMAIL->gettext('download')));
                     continue;
                 }
 
@@ -1172,15 +1198,6 @@
                 // fetch part if not available
                 if (!isset($part->body)) {
                     $part->body = $MESSAGE->get_part_content($part->mime_id);
-                }
-
-                // extract headers from message/rfc822 parts
-                if ($part->mimetype == 'message/rfc822') {
-                    $msgpart = rcube_mime::parse_message($part->body);
-                    if (!empty($msgpart->headers)) {
-                        $part = $msgpart;
-                        $out .= html::div('message-partheaders', rcmail_message_headers(sizeof($header_attrib) ? $header_attrib : null, $part->headers));
-                    }
                 }
 
                 // message is cached but not exists (#1485443), or other error
@@ -1218,7 +1235,7 @@
         if (!rcube_utils::mem_check(strlen($MESSAGE->body) * 10)) {
             $out .= html::span('part-notice', $RCMAIL->gettext('messagetoobig'). ' '
                 . html::a('?_task=mail&_action=get&_download=1&_uid='.$MESSAGE->uid.'&_part=0'
-                    .'&_mbox='. urlencode($RCMAIL->storage->get_folder()), $RCMAIL->gettext('download')));
+                    .'&_mbox='. urlencode($MESSAGE->folder), $RCMAIL->gettext('download')));
         }
         else {
             $plugin = $RCMAIL->plugins->exec_hook('message_body_prefix',
@@ -1772,6 +1789,7 @@
             'Message-ID' => $RCMAIL->gen_message_id(),
             'X-Sender'   => $identity['email'],
             'References' => trim($message->headers->references . ' ' . $message->headers->messageID),
+            'In-Reply-To' => $message->headers->messageID,
         );
 
         $report = "Final-Recipient: rfc822; {$identity['email']}\r\n"
@@ -1787,20 +1805,21 @@
             $report .= "Reporting-UA: $agent\r\n";
         }
 
+        $to   = rcube_mime::decode_mime_string($message->headers->to, $message->headers->charset);
+        $date = $RCMAIL->format_date($message->headers->date, $RCMAIL->config->get('date_long'));
         $body = $RCMAIL->gettext("yourmessage") . "\r\n\r\n" .
-            "\t" . $RCMAIL->gettext("to") . ': ' . rcube_mime::decode_mime_string($message->headers->to, $message->headers->charset) . "\r\n" .
-            "\t" . $RCMAIL->gettext("subject") . ': ' . $message->subject . "\r\n" .
-            "\t" . $RCMAIL->gettext("sent") . ': ' . $RCMAIL->format_date($message->headers->date, $RCMAIL->config->get('date_long')) . "\r\n" .
+            "\t" . $RCMAIL->gettext("to") . ": {$to}\r\n" .
+            "\t" . $RCMAIL->gettext("subject") . ": {$message->subject}\r\n" .
+            "\t" . $RCMAIL->gettext("date") . ": {$date}\r\n" .
             "\r\n" . $RCMAIL->gettext("receiptnote");
 
-        $compose->headers($headers);
+        $compose->headers(array_filter($headers));
         $compose->setContentType('multipart/report', array('report-type'=> 'disposition-notification'));
         $compose->setTXTBody(rcube_mime::wordwrap($body, 75, "\r\n"));
         $compose->addAttachment($report, 'message/disposition-notification', 'MDNPart2.txt', false, '7bit', 'inline');
 
-        if ($RCMAIL->config->get('mdn_use_from')) {
-            $options['mdn_use_from'] = true;
-        }
+        // SMTP options
+        $options = array('mdn_use_from' => (bool) $RCMAIL->config->get('mdn_use_from'));
 
         $sent = $RCMAIL->deliver_message($compose, $identity['email'], $mailto, $smtp_error, $body_file, $options);
 
@@ -1984,7 +2003,7 @@
     $ctypes = array('application/', 'multipart/m', 'multipart/signed', 'multipart/report');
 
     // Build search string of "with attachment" filter
-    $attachment = str_repeat(' OR', count($ctypes)-1);
+    $attachment = trim(str_repeat(' OR', count($ctypes)-1));
     foreach ($ctypes as $type) {
         $attachment .= ' HEADER Content-Type ' . rcube_imap_generic::escape($type);
     }

--
Gitblit v1.9.1