From 8749e94b4bed36500e4f45c65cc16cfd5633ef34 Mon Sep 17 00:00:00 2001
From: Aleksander Machniak <alec@alec.pl>
Date: Fri, 08 Jun 2012 05:14:53 -0400
Subject: [PATCH] Fix attachment sizes in message print page and attachment preview page (#1488515)   - Use size parameter from Content-Disposition header if specified,   - Calculate size of base64 encoded message parts

---
 program/steps/mail/func.inc |  142 ++++++++++++++++++++++++++++++++++++----------
 1 files changed, 110 insertions(+), 32 deletions(-)

diff --git a/program/steps/mail/func.inc b/program/steps/mail/func.inc
index fb8e7fa..5a18ded 100644
--- a/program/steps/mail/func.inc
+++ b/program/steps/mail/func.inc
@@ -17,9 +17,6 @@
  +-----------------------------------------------------------------------+
  | Author: Thomas Bruederli <roundcube@gmail.com>                        |
  +-----------------------------------------------------------------------+
-
- $Id$
-
 */
 
 // setup some global vars used by mail steps
@@ -84,8 +81,8 @@
       $OUTPUT->set_env('search_request', $search_request);
     }
 
-      $search_mods = $RCMAIL->config->get('search_mods', $SEARCH_MODS_DEFAULT);
-      $OUTPUT->set_env('search_mods', $search_mods);
+    $search_mods = $RCMAIL->config->get('search_mods', $SEARCH_MODS_DEFAULT);
+    $OUTPUT->set_env('search_mods', $search_mods);
   }
 
   $threading = (bool) $RCMAIL->storage->get_threading();
@@ -99,6 +96,8 @@
   $OUTPUT->set_env('threads', $threading || $RCMAIL->storage->get_capability('THREAD'));
   $OUTPUT->set_env('preview_pane_mark_read', $RCMAIL->config->get('preview_pane_mark_read', 0));
 
+  if ($CONFIG['delete_junk'])
+    $OUTPUT->set_env('delete_junk', true);
   if ($CONFIG['flag_for_deletion'])
     $OUTPUT->set_env('flag_for_deletion', true);
   if ($CONFIG['read_when_deleted'])
@@ -115,6 +114,9 @@
     $OUTPUT->set_env('drafts_mailbox', $CONFIG['drafts_mbox']);
   if ($CONFIG['junk_mbox'])
     $OUTPUT->set_env('junk_mailbox', $CONFIG['junk_mbox']);
+
+  if (!empty($_SESSION['browser_caps']))
+    $OUTPUT->set_env('browser_capabilities', $_SESSION['browser_caps']);
 
   if (!$OUTPUT->ajax_call)
     $OUTPUT->add_label('checkingmail', 'deletemessage', 'movemessagetotrash',
@@ -228,7 +230,7 @@
   // Make sure there are no duplicated columns (#1486999)
   $a_show_cols = array_unique($a_show_cols);
 
-  // Plugins may set header's list_cols/list_flags and other rcube_mail_header variables
+  // Plugins may set header's list_cols/list_flags and other rcube_message_header variables
   // and list columns
   $plugin = $RCMAIL->plugins->exec_hook('messages_list',
     array('messages' => $a_headers, 'cols' => $a_show_cols));
@@ -882,7 +884,7 @@
 
   // show these headers
   $standard_headers = array('subject', 'from', 'to', 'cc', 'bcc', 'replyto',
-    'mail-reply-to', 'mail-followup-to', 'date');
+    'mail-reply-to', 'mail-followup-to', 'date', 'priority');
   $exclude_headers = $attrib['exclude'] ? explode(',', $attrib['exclude']) : array();
   $output_headers = array();
 
@@ -902,6 +904,13 @@
         $header_value = format_date($value, $RCMAIL->config->get('date_long', 'x'));
       else
         $header_value = format_date($value);
+    }
+    else if ($hkey == 'priority') {
+      if ($value) {
+        $header_value = html::span('prio' . $value, rcmail_localized_priority($value));
+      }
+      else
+        continue;
     }
     else if ($hkey == 'replyto') {
       if ($headers['replyto'] != $headers['from'])
@@ -938,7 +947,7 @@
 
   // single header value is requested
   if (!empty($attrib['valueof']))
-    return Q($plugin['output'][$attrib['valueof']]['value'], ($hkey == 'subject' ? 'strict' : 'show'));
+    return Q($plugin['output'][$attrib['valueof']]['value'], ($attrib['valueof'] == 'subject' ? 'strict' : 'show'));
 
   // compose html table
   $table = new html_table(array('cols' => 2));
@@ -951,6 +960,24 @@
   return $table->show($attrib);
 }
 
+/**
+ * Convert Priority header value into a localized string
+ */
+function rcmail_localized_priority($value)
+{
+  $labels_map = array(
+    '1' => 'highest',
+    '2' => 'high',
+    '3' => 'normal',
+    '4' => 'low',
+    '5' => 'lowest',
+  );
+  
+  if ($value && $labels_map[$value])
+    return rcube_label($labels_map[$value]);
+    
+  return '';
+}
 
 /**
  * return block to show full message headers
@@ -959,8 +986,8 @@
 {
   global $OUTPUT;
 
-  $html = html::div(array('class' => "more-headers show-headers", 'onclick' => "return ".JS_OBJECT_NAME.".command('load-headers','',this)"), '');
-  $html .= html::div(array('id' => "all-headers", 'class' => "all", 'style' => 'display:none'), html::div(array('id' => 'headers-source'), ''));
+  $html = html::div(array('id' => "all-headers", 'class' => "all", 'style' => 'display:none'), html::div(array('id' => 'headers-source'), ''));
+  $html .= html::div(array('class' => "more-headers show-headers", 'onclick' => "return ".JS_OBJECT_NAME.".command('show-headers','',this)"), '');
 
   $OUTPUT->add_gui_object('all_headers_row', 'all-headers');
   $OUTPUT->add_gui_object('all_headers_box', 'headers-source');
@@ -997,10 +1024,20 @@
     foreach ($MESSAGE->parts as $i => $part) {
       if ($part->type == 'headers')
         $out .= rcmail_message_headers(sizeof($header_attrib) ? $header_attrib : NULL, $part->headers);
-      else if ($part->type == 'content' && $part->size) {
+      else if ($part->type == 'content') {
+        // unsapported
+        if ($part->realtype) {
+          if ($part->realtype == 'multipart/encrypted') {
+            $out .= html::span('part-notice', rcube_label('encryptedmessage'));
+          }
+          continue;
+        }
+        else if (!$part->size) {
+          continue;
+        }
         // Check if we have enough memory to handle the message in it
         // #1487424: we need up to 10x more memory than the body
-        if (!rcmail_mem_check($part->size * 10)) {
+        else if (!rcmail_mem_check($part->size * 10)) {
           $out .= html::span('part-notice', rcube_label('messagetoobig'). ' '
             . html::a('?_task=mail&_action=get&_download=1&_uid='.$MESSAGE->uid.'&_part='.$part->mime_id
               .'&_mbox='. urlencode($RCMAIL->storage->get_folder()), rcube_label('download')));
@@ -1069,12 +1106,7 @@
       }
 
       // Content-Type: image/*...
-      if (preg_match('/^image\//i', $attach_prop->mimetype) ||
-        // ...or known file extension: many clients are using application/octet-stream
-        ($attach_prop->filename &&
-          preg_match('/^application\/octet-stream$/i', $attach_prop->mimetype) &&
-          preg_match('/\.(jpg|jpeg|png|gif|bmp)$/i', $attach_prop->filename))
-      ) {
+      if (rcmail_part_image_type($attach_prop)) {
         $out .= html::tag('hr') . html::p(array('align' => "center"),
           html::img(array(
             'src' => $MESSAGE->get_part_url($attach_prop->mime_id, true),
@@ -1092,6 +1124,48 @@
   return html::div($attrib, $out);
 }
 
+function rcmail_part_image_type($part)
+{
+  $rcmail = rcmail::get_instance();
+
+  // Skip TIFF images if browser doesn't support this format...
+  $tiff_support = !empty($_SESSION['browser_caps']) && !empty($_SESSION['browser_caps']['tif']);
+  // until we can convert them to JPEG
+  $tiff_support = $tiff_support || $rcmail->config->get('im_convert_path');
+
+  // Content-type regexp
+  $mime_regex = $tiff_support ? '/^image\//i' : '/^image\/(?!tif)/i';
+
+  // Content-Type: image/*...
+  if (preg_match($mime_regex, $part->mimetype)) {
+    return $part->mimetype;
+  }
+
+  // Many clients use application/octet-stream, we'll detect mimetype
+  // by checking filename extension
+
+  // Supported image filename extensions to image type map
+  $types = array(
+    'jpg'  => 'image/jpeg',
+    'jpeg' => 'image/jpeg',
+    'png'  => 'image/png',
+    'gif'  => 'image/gif',
+    'bmp'  => 'image/bmp',
+  );
+  if ($tiff_support) {
+    $types['tif']  = 'image/tiff';
+    $types['tiff'] = 'image/tiff';
+  }
+
+  if ($part->filename
+    && preg_match('/^application\/octet-stream$/i', $part->mimetype)
+    && preg_match('/\.([^.])$/i', $part->filename, $m)
+    && ($extension = strtolower($m[1]))
+    && isset($types[$extension])
+  ) {
+    return $types[$extension];
+  }
+}
 
 /**
  * Convert all relative URLs according to a <base> in HTML
@@ -1119,14 +1193,15 @@
   // find STYLE tags
   while (($pos = stripos($body, '<style', $last_style_pos)) && ($pos2 = stripos($body, '</style>', $pos)))
   {
-    $pos = strpos($body, '>', $pos)+1;
+    $pos = strpos($body, '>', $pos) + 1;
+    $len = $pos2 - $pos;
 
     // replace all css definitions with #container [def]
-    $styles = rcmail_mod_css_styles(
-      substr($body, $pos, $pos2-$pos), $cont_id, $allow_remote);
+    $styles = substr($body, $pos, $len);
+    $styles = rcmail_mod_css_styles($styles, $cont_id, $allow_remote);
 
-    $body = substr_replace($body, $styles, $pos, $pos2-$pos);
-    $last_style_pos = $pos2;
+    $body = substr_replace($body, $styles, $pos, $len);
+    $last_style_pos = $pos2 + strlen($styles) - $len;
   }
 
   // modify HTML links to open a new window if clicked
@@ -1303,7 +1378,7 @@
       if ($addicon && $_SESSION['writeable_abook']) {
         $address = html::span(null, $address . html::a(array(
             'href' => "#add",
-            'onclick' => sprintf("return %s.command('add-contact','%s',this)", JS_OBJECT_NAME, urlencode($string)),
+            'onclick' => sprintf("return %s.command('add-contact','%s',this)", JS_OBJECT_NAME, $string),
             'title' => rcube_label('addtoaddressbook'),
             'class' => 'rcmaddcontact',
           ),
@@ -1402,25 +1477,28 @@
 
 function rcmail_message_part_controls($attrib)
 {
-  global $MESSAGE;
+  global $MESSAGE, $RCMAIL;
 
   $part = asciiwords(get_input_value('_part', RCUBE_INPUT_GPC));
   if (!is_object($MESSAGE) || !is_array($MESSAGE->parts) || !($_GET['_uid'] && $_GET['_part']) || !$MESSAGE->mime_parts[$part])
     return '';
 
-  $part = $MESSAGE->mime_parts[$part];
+  $part  = $MESSAGE->mime_parts[$part];
   $table = new html_table(array('cols' => 3));
 
-  if (!empty($part->filename)) {
+  $filename = $part->filename;
+  if (empty($filename) && $attach_prop->mimetype == 'text/html') {
+    $filename = rcube_label('htmlmessage');
+  }
+
+  if (!empty($filename)) {
     $table->add('title', Q(rcube_label('filename')));
-    $table->add('header', Q($part->filename));
+    $table->add('header', Q($filename));
     $table->add('download-link', html::a(array('href' => './?'.str_replace('_frame=', '_download=', $_SERVER['QUERY_STRING'])), Q(rcube_label('download'))));
   }
 
-  if (!empty($part->size)) {
-    $table->add('title', Q(rcube_label('filesize')));
-    $table->add('header', Q(show_bytes($part->size)));
-  }
+  $table->add('title', Q(rcube_label('filesize')));
+  $table->add('header', Q($RCMAIL->message_part_size($part)));
 
   return $table->show($attrib);
 }

--
Gitblit v1.9.1