From 4af76d20cafcd456bf3ce0fcb17b25a888c45160 Mon Sep 17 00:00:00 2001 From: Thomas <thomas@roundcube.net> Date: Mon, 21 Oct 2013 15:14:46 -0400 Subject: [PATCH] Bump version --- program/lib/Roundcube/rcube_message.php | 118 ++++++++++++++++++++++++++++++++++++----------------------- 1 files changed, 72 insertions(+), 46 deletions(-) diff --git a/program/lib/Roundcube/rcube_message.php b/program/lib/Roundcube/rcube_message.php index f41493d..a8bcf6a 100644 --- a/program/lib/Roundcube/rcube_message.php +++ b/program/lib/Roundcube/rcube_message.php @@ -85,15 +85,16 @@ $this->headers = $this->storage->get_message($uid); - if (!$this->headers) + if (!$this->headers) { return; + } $this->mime = new rcube_mime($this->headers->charset); - $this->subject = $this->mime->decode_mime_string($this->headers->subject); + $this->subject = $this->headers->get('subject'); list(, $this->sender) = each($this->mime->decode_address_list($this->headers->from, 1)); - $this->set_safe((intval($_GET['_safe']) || $_SESSION['safe_messages'][$uid])); + $this->set_safe((intval($_GET['_safe']) || $_SESSION['safe_messages'][$this->folder.':'.$uid])); $this->opt = array( 'safe' => $this->is_safe, 'prefer_html' => $this->app->config->get('prefer_html'), @@ -125,15 +126,11 @@ */ public function get_header($name, $raw = false) { - if (empty($this->headers)) + if (empty($this->headers)) { return null; + } - if ($this->headers->$name) - $value = $this->headers->$name; - else if ($this->headers->others[$name]) - $value = $this->headers->others[$name]; - - return $raw ? $value : $this->mime->decode_header($value); + return $this->headers->get($name, !$raw); } @@ -144,8 +141,7 @@ */ public function set_safe($safe = true) { - $this->is_safe = $safe; - $_SESSION['safe_messages'][$this->uid] = $this->is_safe; + $_SESSION['safe_messages'][$this->folder.':'.$this->uid] = $this->is_safe = $safe; } @@ -153,12 +149,13 @@ * Compose a valid URL for getting a message part * * @param string $mime_id Part MIME-ID + * @param mixed $embed Mimetype class for parts to be embedded * @return string URL or false if part does not exist */ public function get_part_url($mime_id, $embed = false) { if ($this->mime_parts[$mime_id]) - return $this->opt['get_url'] . '&_part=' . $mime_id . ($embed ? '&_embed=1' : ''); + return $this->opt['get_url'] . '&_part=' . $mime_id . ($embed ? '&_embed=1&_mimeclass=' . $embed : ''); else return false; } @@ -210,18 +207,20 @@ if (!$recursive) { $level = explode('.', $part->mime_id); - // Skip if level too deep or part has a file name - if (count($level) > 2 || $part->filename) { + // Skip if part is an attachment + if ($this->is_attachment($part)) { continue; } - // HTML part can be on the lower level, if not... - if (count($level) > 1) { - array_pop($level); + // Check if the part belongs to higher-level's alternative/related + while (array_pop($level) !== null) { + if (!count($level)) { + return true; + } + $parent = $this->mime_parts[join('.', $level)]; - // ... parent isn't multipart/alternative or related if ($parent->mimetype != 'multipart/alternative' && $parent->mimetype != 'multipart/related') { - continue; + continue 2; } } } @@ -271,7 +270,7 @@ $out = $this->get_part_content($mime_id); // create instance of html2text class - $txt = new html2text($out); + $txt = new rcube_html2text($out); return $txt->get_text(); } } @@ -322,7 +321,7 @@ // parse headers from message/rfc822 part if (!isset($structure->headers['subject'])) { - list($headers, $dump) = explode("\r\n\r\n", $this->get_part_content($structure->mime_id, null, true, 4096)); + list($headers, $dump) = explode("\r\n\r\n", $this->get_part_content($structure->mime_id, null, true, 32768)); $structure->headers = rcube_mime::parse_headers($headers); } } @@ -330,10 +329,11 @@ $mimetype = $structure->mimetype; // show message headers - if ($recursive && is_array($structure->headers) && isset($structure->headers['subject'])) { + if ($recursive && is_array($structure->headers) && + ($structure->headers['subject'] || $structure->headers['from'] || $structure->headers['to'])) { $c = new stdClass; $c->type = 'headers'; - $c->headers = &$structure->headers; + $c->headers = $structure->headers; $this->parts[] = $c; } @@ -350,45 +350,59 @@ // print body if message doesn't have multiple parts if ($message_ctype_primary == 'text' && !$recursive) { + // parts with unsupported type add to attachments list + if (!in_array($message_ctype_secondary, array('plain', 'html', 'enriched'))) { + $this->attachments[] = $structure; + return; + } + $structure->type = 'content'; - $this->parts[] = &$structure; + $this->parts[] = $structure; // Parse simple (plain text) message body - if ($message_ctype_secondary == 'plain') + if ($message_ctype_secondary == 'plain') { foreach ((array)$this->uu_decode($structure) as $uupart) { $this->mime_parts[$uupart->mime_id] = $uupart; $this->attachments[] = $uupart; } + } } // the same for pgp signed messages else if ($mimetype == 'application/pgp' && !$recursive) { $structure->type = 'content'; - $this->parts[] = &$structure; + $this->parts[] = $structure; } // message contains (more than one!) alternative parts else if ($mimetype == 'multipart/alternative' && is_array($structure->parts) && count($structure->parts) > 1 ) { - // get html/plaintext parts - $plain_part = $html_part = $print_part = $related_part = null; + $plain_part = null; + $html_part = null; + $print_part = null; + $related_part = null; + $attach_part = null; + // get html/plaintext parts, other add to attachments list foreach ($structure->parts as $p => $sub_part) { $sub_mimetype = $sub_part->mimetype; + $is_multipart = preg_match('/^multipart\/(related|relative|mixed|alternative)/', $sub_mimetype); // skip empty text parts - if (!$sub_part->size && preg_match('#^text/(plain|html|enriched)$#', $sub_mimetype)) { + if (!$sub_part->size && !$is_multipart) { continue; } // check if sub part is - if ($sub_mimetype == 'text/plain') + if ($is_multipart) + $related_part = $p; + else if ($sub_mimetype == 'text/plain') $plain_part = $p; else if ($sub_mimetype == 'text/html') $html_part = $p; else if ($sub_mimetype == 'text/enriched') $enriched_part = $p; - else if (in_array($sub_mimetype, array('multipart/related', 'multipart/mixed', 'multipart/alternative'))) - $related_part = $p; + else + $attach_part = $p; } // parse related part (alternative part could be in here) @@ -404,13 +418,13 @@ // choose html/plain part to print if ($html_part !== null && $this->opt['prefer_html']) { - $print_part = &$structure->parts[$html_part]; + $print_part = $structure->parts[$html_part]; } else if ($enriched_part !== null) { - $print_part = &$structure->parts[$enriched_part]; + $print_part = $structure->parts[$enriched_part]; } else if ($plain_part !== null) { - $print_part = &$structure->parts[$plain_part]; + $print_part = $structure->parts[$plain_part]; } // add the right message body @@ -432,10 +446,15 @@ // add html part as attachment if ($html_part !== null && $structure->parts[$html_part] !== $print_part) { - $html_part = &$structure->parts[$html_part]; + $html_part = $structure->parts[$html_part]; $html_part->mimetype = 'text/html'; $this->attachments[] = $html_part; + } + + // add unsupported/unrecognized parts to attachments list + if ($attach_part) { + $this->attachments[] = $structure->parts[$attach_part]; } } // this is an ecrypted message -> create a plaintext body with the according message @@ -446,6 +465,17 @@ $p->ctype_secondary = 'plain'; $p->mimetype = 'text/plain'; $p->realtype = 'multipart/encrypted'; + + $this->parts[] = $p; + } + // this is an S/MIME ecrypted message -> create a plaintext body with the according message + else if ($mimetype == 'application/pkcs7-mime') { + $p = new stdClass; + $p->type = 'content'; + $p->ctype_primary = 'text'; + $p->ctype_secondary = 'plain'; + $p->mimetype = 'text/plain'; + $p->realtype = 'application/pkcs7-mime'; $this->parts[] = $p; } @@ -541,7 +571,7 @@ continue; // part belongs to a related message and is linked - if ($mimetype == 'multipart/related' + if (preg_match('/^multipart\/(related|relative)/', $mimetype) && ($mail_part->headers['content-id'] || $mail_part->headers['content-location'])) { if ($mail_part->headers['content-id']) $mail_part->content_id = preg_replace(array('/^</', '/>$/'), '', $mail_part->headers['content-id']); @@ -561,9 +591,6 @@ // regular attachment with valid content type // (content-type name regexp according to RFC4288.4.2) else if (preg_match('/^[a-z0-9!#$&.+^_-]+\/[a-z0-9!#$&.+^_-]+$/i', $part_mimetype)) { - if (!$mail_part->filename) - $mail_part->filename = 'Part '.$mail_part->mime_id; - $this->attachments[] = $mail_part; } // attachment with invalid content type @@ -583,13 +610,13 @@ } // if this was a related part try to resolve references - if ($mimetype == 'multipart/related' && sizeof($this->inline_parts)) { + if (preg_match('/^multipart\/(related|relative)/', $mimetype) && sizeof($this->inline_parts)) { $a_replaces = array(); $img_regexp = '/^image\/(gif|jpe?g|png|tiff|bmp|svg)/'; foreach ($this->inline_parts as $inline_object) { - $part_url = $this->get_part_url($inline_object->mime_id, true); - if ($inline_object->content_id) + $part_url = $this->get_part_url($inline_object->mime_id, $inline_object->ctype_primary); + if (isset($inline_object->content_id)) $a_replaces['cid:'.$inline_object->content_id] = $part_url; if ($inline_object->content_location) { $a_replaces[$inline_object->content_location] = $part_url; @@ -628,7 +655,6 @@ } // message is a single part non-text (without filename) else if (preg_match('/application\//i', $mimetype)) { - $structure->filename = 'Part '.$structure->mime_id; $this->attachments[] = $structure; } } @@ -730,7 +756,7 @@ $uupart->size = strlen($uupart->body); $uupart->mime_id = 'uu.' . $part->mime_id . '.' . $pid; - $ctype = rcube_mime::content_type($uupart->body, $uupart->filename, 'application/octet-stream', true); + $ctype = rcube_mime::file_content_type($uupart->body, $uupart->filename, 'application/octet-stream', true); $uupart->mimetype = $ctype; list($uupart->ctype_primary, $uupart->ctype_secondary) = explode('/', $ctype); -- Gitblit v1.9.1