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 | 133 +++++++++++++++++++++++++++-----------------
1 files changed, 82 insertions(+), 51 deletions(-)
diff --git a/program/lib/Roundcube/rcube_message.php b/program/lib/Roundcube/rcube_message.php
index 87319f0..a8bcf6a 100644
--- a/program/lib/Roundcube/rcube_message.php
+++ b/program/lib/Roundcube/rcube_message.php
@@ -2,8 +2,6 @@
/*
+-----------------------------------------------------------------------+
- | program/include/rcube_message.php |
- | |
| This file is part of the Roundcube Webmail client |
| Copyright (C) 2008-2010, The Roundcube Dev Team |
| |
@@ -18,7 +16,6 @@
| Author: Thomas Bruederli <roundcube@gmail.com> |
+-----------------------------------------------------------------------+
*/
-
/**
* Logical representation of a mail message with all its data
@@ -88,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'),
@@ -128,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);
}
@@ -147,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;
}
@@ -156,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;
}
@@ -173,10 +167,11 @@
* @param string $mime_id Part MIME-ID
* @param resource $fp File pointer to save the message part
* @param boolean $skip_charset_conv Disables charset conversion
+ * @param int $max_bytes Only read this number of bytes
*
* @return string Part content
*/
- public function get_part_content($mime_id, $fp = null, $skip_charset_conv = false)
+ public function get_part_content($mime_id, $fp = null, $skip_charset_conv = false, $max_bytes = 0)
{
if ($part = $this->mime_parts[$mime_id]) {
// stored in message structure (winmail/inline-uuencode)
@@ -190,7 +185,7 @@
// get from IMAP
$this->storage->set_folder($this->folder);
- return $this->storage->get_message_part($this->uid, $mime_id, $part, NULL, $fp, $skip_charset_conv);
+ return $this->storage->get_message_part($this->uid, $mime_id, $part, NULL, $fp, $skip_charset_conv, $max_bytes);
}
}
@@ -212,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;
}
}
}
@@ -273,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();
}
}
@@ -319,16 +316,24 @@
private function parse_structure($structure, $recursive = false)
{
// real content-type of message/rfc822 part
- if ($structure->mimetype == 'message/rfc822' && $structure->real_mimetype)
+ if ($structure->mimetype == 'message/rfc822' && $structure->real_mimetype) {
$mimetype = $structure->real_mimetype;
+
+ // 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, 32768));
+ $structure->headers = rcube_mime::parse_headers($headers);
+ }
+ }
else
$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;
}
@@ -345,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)
@@ -399,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
@@ -427,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
@@ -441,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;
}
@@ -536,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']);
@@ -556,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
@@ -578,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;
@@ -623,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;
}
}
@@ -725,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