From 0e32d7032b54838607e071588fd30ff8b13fc7fe Mon Sep 17 00:00:00 2001
From: Aleksander Machniak <alec@alec.pl>
Date: Fri, 15 Mar 2013 07:50:53 -0400
Subject: [PATCH] Fix load-attachment link

---
 program/steps/mail/func.inc |  155 +++++++++++++++++++++++----------------------------
 1 files changed, 71 insertions(+), 84 deletions(-)

diff --git a/program/steps/mail/func.inc b/program/steps/mail/func.inc
index 88391b1..8c97439 100644
--- a/program/steps/mail/func.inc
+++ b/program/steps/mail/func.inc
@@ -89,11 +89,12 @@
   }
 
   $threading = (bool) $RCMAIL->storage->get_threading();
+  $delimiter = $RCMAIL->storage->get_hierarchy_delimiter();
 
   // set current mailbox and some other vars in client environment
   $OUTPUT->set_env('mailbox', $mbox_name);
   $OUTPUT->set_env('pagesize', $RCMAIL->storage->get_pagesize());
-  $OUTPUT->set_env('delimiter', $RCMAIL->storage->get_hierarchy_delimiter());
+  $OUTPUT->set_env('delimiter', $delimiter);
   $OUTPUT->set_env('threading', $threading);
   $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));
@@ -121,7 +122,10 @@
       'movingmessage', 'copyingmessage', 'deletingmessage', 'markingmessage',
       'copy', 'move', 'quota');
 
-  $OUTPUT->set_pagetitle(rcmail_localize_foldername($RCMAIL->storage->mod_folder($mbox_name)));
+  $pagetitle = $RCMAIL->localize_foldername($RCMAIL->storage->mod_folder($mbox_name), true);
+  $pagetitle = str_replace($delimiter, " \xC2\xBB ", $pagetitle);
+
+  $OUTPUT->set_pagetitle($pagetitle);
 }
 
 /**
@@ -628,39 +632,6 @@
 
   $p += array('safe' => false, 'inline_html' => true);
 
-  // special replacements (not properly handled by washtml class)
-  $html_search = array(
-    '/(<\/nobr>)(\s+)(<nobr>)/i',	// space(s) between <NOBR>
-    '/<title[^>]*>[^<]*<\/title>/i',	// PHP bug #32547 workaround: remove title tag
-    '/^(\0\0\xFE\xFF|\xFF\xFE\0\0|\xFE\xFF|\xFF\xFE|\xEF\xBB\xBF)/',	// byte-order mark (only outlook?)
-    '/<html\s[^>]+>/i',			// washtml/DOMDocument cannot handle xml namespaces
-  );
-  $html_replace = array(
-    '\\1'.' &nbsp; '.'\\3',
-    '',
-    '',
-    '<html>',
-  );
-  $html = preg_replace($html_search, $html_replace, trim($html));
-
-  // PCRE errors handling (#1486856), should we use something like for every preg_* use?
-  if ($html === null && ($preg_error = preg_last_error()) != PREG_NO_ERROR) {
-    $errstr = "Could not clean up HTML message! PCRE Error: $preg_error.";
-
-    if ($preg_error == PREG_BACKTRACK_LIMIT_ERROR)
-      $errstr .= " Consider raising pcre.backtrack_limit!";
-    if ($preg_error == PREG_RECURSION_LIMIT_ERROR)
-      $errstr .= " Consider raising pcre.recursion_limit!";
-
-    raise_error(array('code' => 620, 'type' => 'php',
-        'line' => __LINE__, 'file' => __FILE__,
-        'message' => $errstr), true, false);
-    return '';
-  }
-
-  // fix (unknown/malformed) HTML tags before "wash"
-  $html = preg_replace_callback('/(<[\/]*)([^\s>]+)/', 'rcmail_html_tag_callback', $html);
-
   // charset was converted to UTF-8 in rcube_storage::get_message_part(),
   // change/add charset specification in HTML accordingly,
   // washtml cannot work without that
@@ -673,9 +644,6 @@
   if (!$rcount) {
     $html = '<head>' . $meta . '</head>' . $html;
   }
-
-  // turn relative into absolute urls
-  $html = rcmail_resolve_base($html);
 
   // clean HTML with washhtml by Frederic Motte
   $wash_opts = array(
@@ -702,7 +670,7 @@
     $wash_opts['html_attribs'] = $p['html_attribs'];
 
   // initialize HTML washer
-  $washer = new washtml($wash_opts);
+  $washer = new rcube_washtml($wash_opts);
 
   if (!$p['skip_washer_form_callback'])
     $washer->add_callback('form', 'rcmail_washtml_callback');
@@ -739,8 +707,11 @@
         + $p + array('safe' => false, 'plain' => false, 'inline_html' => true));
 
   // convert html to text/plain
-  if ($data['type'] == 'html' && $data['plain']) {
-    $txt = new html2text($data['body'], false, true);
+  if ($data['plain'] && ($data['type'] == 'html' || $data['type'] == 'enriched')) {
+    if ($data['type'] == 'enriched') {
+      $data['body'] = rcube_enriched::to_html($data['body']);
+    }
+    $txt = new rcube_html2text($data['body'], false, true);
     $body = $txt->get_text();
     $part->ctype_secondary = 'plain';
   }
@@ -921,22 +892,6 @@
 
 
 /**
- * Callback function for HTML tags fixing
- */
-function rcmail_html_tag_callback($matches)
-{
-  $tagname = $matches[2];
-
-  $tagname = preg_replace(array(
-    '/:.*$/',			// Microsoft's Smart Tags <st1:xxxx>
-    '/[^a-z0-9_\[\]\!-]/i',	// forbidden characters
-    ), '', $tagname);
-
-  return $matches[1].$tagname;
-}
-
-
-/**
  * return table with message headers
  */
 function rcmail_message_headers($attrib, $headers=null)
@@ -967,7 +922,7 @@
   }
 
   // show these headers
-  $standard_headers = array('subject', 'from', 'to', 'cc', 'bcc', 'replyto',
+  $standard_headers = array('subject', 'from', 'sender', 'to', 'cc', 'bcc', 'replyto',
     'mail-reply-to', 'mail-followup-to', 'date', 'priority');
   $exclude_headers = $attrib['exclude'] ? explode(',', $attrib['exclude']) : array();
   $output_headers = array();
@@ -1012,6 +967,14 @@
       if ($headers['mail-replyto'] != $headers['reply-to']
         && $headers['reply-to'] != $headers['from']
       ) {
+        $header_value = rcmail_address_string($value, $attrib['max'], true, $attrib['addicon'], $headers['charset'], $header_title);
+        $ishtml = true;
+      }
+      else
+        continue;
+    }
+    else if ($hkey == 'sender') {
+      if ($headers['sender'] != $headers['from']) {
         $header_value = rcmail_address_string($value, $attrib['max'], true, $attrib['addicon'], $headers['charset'], $header_title);
         $ishtml = true;
       }
@@ -1123,9 +1086,9 @@
         $out .= html::div('message-partheaders', rcmail_message_headers(sizeof($header_attrib) ? $header_attrib : null, $part->headers));
       }
       else if ($part->type == 'content') {
-        // unsapported
+        // unsupported (e.g. encrypted)
         if ($part->realtype) {
-          if ($part->realtype == 'multipart/encrypted') {
+          if ($part->realtype == 'multipart/encrypted' || $part->realtype == 'application/pkcs7-mime') {
             $out .= html::span('part-notice', rcube_label('encryptedmessage'));
           }
           continue;
@@ -1222,10 +1185,9 @@
           $show_link = array(
             'href' => $MESSAGE->get_part_url($attach_prop->mime_id, false),
             'onclick' => sprintf(
-              'return %s.command(\'load-attachment\',{part:\'%s\', mimetype:\'%s\'},this)',
+              'return %s.command(\'load-attachment\',\'%s\',this)',
               JS_OBJECT_NAME,
-              $attach_prop->mime_id,
-              $mimetype)
+              $attach_prop->mime_id)
           );
           $out .= html::p('image-attachment',
              html::a($show_link + array('class' => 'image-link', 'style' => sprintf('width:%dpx', $thumbnail_size)),
@@ -1282,7 +1244,7 @@
 
   // Content-Type: image/*...
   if (preg_match($mime_regex, $part->mimetype)) {
-    return $part->mimetype;
+    return rcmail_fix_mimetype($part->mimetype);
   }
 
   // Many clients use application/octet-stream, we'll detect mimetype
@@ -1309,20 +1271,6 @@
   ) {
     return $types[$extension];
   }
-}
-
-/**
- * Convert all relative URLs according to a <base> in HTML
- */
-function rcmail_resolve_base($body)
-{
-  // check for <base href=...>
-  if (preg_match('!(<base.*href=["\']?)([hftps]{3,5}://[a-z0-9/.%-]+)!i', $body, $regs)) {
-    $replacer = new rcube_base_replacer($regs[2]);
-    $body     = $replacer->replace($body);
-  }
-
-  return $body;
 }
 
 
@@ -1498,6 +1446,11 @@
     $mailto = $part['mailto'];
     $string = $part['string'];
 
+    // phishing email prevention (#1488981), e.g. "valid@email.addr <phishing@email.addr>"
+    if ($name && $name != $mailto && strpos($name, '@')) {
+      $name = '';
+    }
+
     // IDNA ASCII to Unicode
     if ($name == $mailto)
       $name = rcube_idn_to_utf8($name);
@@ -1656,10 +1609,7 @@
   $part  = $MESSAGE->mime_parts[$part];
   $table = new html_table(array('cols' => 3));
 
-  $filename = $part->filename;
-  if (empty($filename) && $attach_prop->mimetype == 'text/html') {
-    $filename = rcube_label('htmlmessage');
-  }
+  $filename = rcmail_attachment_name($part);
 
   if (!empty($filename)) {
     $table->add('title', Q(rcube_label('filename')));
@@ -1672,7 +1622,6 @@
 
   return $table->show($attrib);
 }
-
 
 
 function rcmail_message_part_frame($attrib)
@@ -1749,6 +1698,9 @@
     if ($agent = $RCMAIL->config->get('useragent'))
       $headers['User-Agent'] = $agent;
 
+    if ($RCMAIL->config->get('mdn_use_from'))
+      $options['mdn_use_from'] = true;
+
     $body = rcube_label("yourmessage") . "\r\n\r\n" .
       "\t" . rcube_label("to") . ': ' . rcube_mime::decode_mime_string($message->headers->to, $message->headers->charset) . "\r\n" .
       "\t" . rcube_label("subject") . ': ' . $message->subject . "\r\n" .
@@ -1770,7 +1722,7 @@
     $compose->setTXTBody(rc_wordwrap($body, 75, "\r\n"));
     $compose->addAttachment($report, 'message/disposition-notification', 'MDNPart2.txt', false, '7bit', 'inline');
 
-    $sent = rcmail_deliver_message($compose, $identity['email'], $mailto, $smtp_error, $body_file);
+    $sent = rcmail_deliver_message($compose, $identity['email'], $mailto, $smtp_error, $body_file, $options);
 
     if ($sent)
     {
@@ -1892,9 +1844,44 @@
   if (preg_match('/^application\/pdf.+/', $name))
     $name = 'application/pdf';
 
+  // treat image/pjpeg as image/jpeg
+  else if (preg_match('/^image\/p?jpe?g$/', $name))
+    $name = 'image/jpeg';
+
   return $name;
 }
 
+// return attachment filename, handle empty filename case
+function rcmail_attachment_name($attachment, $display = false)
+{
+    $filename = $attachment->filename;
+
+    if ($filename === null || $filename === '') {
+        if ($attachment->mimetype == 'text/html') {
+            $filename = rcube_label('htmlmessage');
+        }
+        else {
+            $ext      = (array) rcube_mime::get_mime_extensions($attachment->mimetype);
+            $ext      = array_shift($ext);
+            $filename = rcube_label('messagepart') . ' ' . $attachment->mime_id;
+            if ($ext) {
+                $filename .= '.' . $ext;
+            }
+        }
+    }
+
+    $filename = preg_replace('[\r\n]', '', $filename);
+
+    // Display smart names for some known mimetypes
+    if ($display) {
+        if (preg_match('/application\/(pgp|pkcs7)-signature/i', $attachment->mimetype)) {
+            $filename = rcube_label('digitalsig');
+        }
+    }
+
+    return $filename;
+}
+
 function rcmail_search_filter($attrib)
 {
   global $OUTPUT, $CONFIG;

--
Gitblit v1.9.1