Fix handling of message/rfc822 attachments on replies and forwards (#1490607)

Conflicts:

	CHANGELOG
	program/lib/Roundcube/rcube_message.php
	program/steps/mail/compose.inc
	program/steps/mail/func.inc
release-1.0
Aleksander Machniak 9 years ago
parent 6402eb7f78
commit 5579ef6621

@ -4,6 +4,7 @@ CHANGELOG Roundcube Webmail
- Add workaround for https://bugs.php.net/bug.php?id=70757 (#1490582)
- Fix HTML sanitizer to skip <!-- node type X --> in output (#1490583)
- Fix charset encoding of message/rfc822 part bodies (#1490606)
- Fix handling of message/rfc822 attachments on replies and forwards (#1490607)
RELEASE 1.0.7
-------------

@ -525,24 +525,16 @@ class rcube_message
$mail_part = &$structure->parts[$i];
$primary_type = $mail_part->ctype_primary;
$secondary_type = $mail_part->ctype_secondary;
$part_mimetype = $mail_part->mimetype;
// real content-type of message/rfc822
if ($mail_part->real_mimetype) {
$part_orig_mimetype = $mail_part->mimetype;
$part_mimetype = $mail_part->real_mimetype;
list($primary_type, $secondary_type) = explode('/', $part_mimetype);
}
else {
$part_mimetype = $part_orig_mimetype = $mail_part->mimetype;
}
// multipart/alternative
if ($primary_type == 'multipart') {
// multipart/alternative or message/rfc822
if ($primary_type == 'multipart' || $part_mimetype == 'message/rfc822') {
$this->parse_structure($mail_part, true);
// list message/rfc822 as attachment as well (mostly .eml)
if ($part_orig_mimetype == 'message/rfc822' && !empty($mail_part->filename))
if ($primary_type == 'message' && !empty($mail_part->filename)) {
$this->attachments[] = $mail_part;
}
}
// part text/[plain|html] or delivery status
else if ((($part_mimetype == 'text/plain' || $part_mimetype == 'text/html') && $mail_part->disposition != 'attachment') ||
@ -553,8 +545,9 @@ class rcube_message
array('object' => $this, 'structure' => $mail_part,
'mimetype' => $part_mimetype, 'recursive' => true));
if ($plugin['abort'])
if ($plugin['abort']) {
continue;
}
if ($part_mimetype == 'text/html' && $mail_part->size) {
$got_html_part = true;
@ -577,14 +570,6 @@ class rcube_message
$this->attachments[] = $mail_part;
}
}
// part message/*
else if ($primary_type == 'message') {
$this->parse_structure($mail_part, true);
// list as attachment as well (mostly .eml)
if (!empty($mail_part->filename))
$this->attachments[] = $mail_part;
}
// ignore "virtual" protocol parts
else if ($primary_type == 'protocol') {
continue;
@ -608,7 +593,8 @@ class rcube_message
// part belongs to a related message and is linked
if (preg_match('/^multipart\/(related|relative)/', $mimetype)
&& ($mail_part->headers['content-id'] || $mail_part->headers['content-location'])) {
&& ($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']);
if ($mail_part->headers['content-location'])
@ -616,14 +602,6 @@ class rcube_message
$this->inline_parts[] = $mail_part;
}
// attachment encapsulated within message/rfc822 part needs further decoding (#1486743)
else if ($part_orig_mimetype == 'message/rfc822') {
$this->parse_structure($mail_part, true);
// list as attachment as well (mostly .eml)
if (!empty($mail_part->filename))
$this->attachments[] = $mail_part;
}
// 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)) {
@ -639,9 +617,13 @@ class rcube_message
$this->attachments[] = $mail_part;
}
}
// attachment part as message/rfc822 (#1488026)
else if ($mail_part->mimetype == 'message/rfc822') {
$this->parse_structure($mail_part);
// calendar part not marked as attachment (#1490325)
else if ($part_mimetype == 'text/calendar') {
if (!$mail_part->filename) {
$mail_part->filename = 'calendar.ics';
}
$this->attachments[] = $mail_part;
}
}

@ -716,11 +716,9 @@ function rcmail_prepare_message_body()
if (!empty($MESSAGE->parts)) {
// collect IDs of message/rfc822 parts
if ($compose_mode == RCUBE_COMPOSE_EDIT || $compose_mode == RCUBE_COMPOSE_DRAFT) {
foreach ($MESSAGE->attachments as $part) {
if ($part->mimetype == 'message/rfc822') {
$messages[] = $part->mime_id;
}
foreach ($MESSAGE->mime_parts as $part) {
if ($part->mimetype == 'message/rfc822') {
$messages[] = $part->mime_id;
}
}
@ -730,7 +728,7 @@ function rcmail_prepare_message_body()
continue;
}
// skip all content parts inside the message/rfc822 part in DRAFT/EDIT mode
// skip all content parts inside the message/rfc822 part
foreach ($messages as $mimeid) {
if (strpos($part->mime_id, $mimeid . '.') === 0) {
continue 2;
@ -1163,6 +1161,10 @@ function rcmail_write_compose_attachments(&$message, $bodyIsHtml)
$messages = array();
foreach ((array)$message->mime_parts as $pid => $part) {
if ($part->mimetype == 'message/rfc822') {
$messages[] = $part->mime_id;
}
if ($part->disposition == 'attachment' || ($part->disposition == 'inline' && $bodyIsHtml) || $part->filename) {
// skip parts that aren't valid attachments
if ($part->ctype_primary == 'multipart' || $part->mimetype == 'application/ms-tnef') {
@ -1179,23 +1181,10 @@ function rcmail_write_compose_attachments(&$message, $bodyIsHtml)
continue;
}
// skip message/rfc822 attachments on forwards (#1489214)
// Thunderbird when forwarding in inline mode displays such attachments
// and skips any attachments from inside of such part, this however
// skipped e.g. images used in HTML body or other attachments. So,
// better to skip .eml attachments but not their content (included files).
if ($part->mimetype == 'message/rfc822') {
if ($compose_mode == RCUBE_COMPOSE_FORWARD) {
continue;
}
$messages[] = $part->mime_id;
}
else if ($compose_mode != RCUBE_COMPOSE_FORWARD) {
// skip attachments included in message/rfc822 attachment (#1486487)
foreach ($messages as $mimeid) {
if (strpos($part->mime_id, $mimeid . '.') === 0) {
continue 2;
}
// skip attachments included in message/rfc822 attachment (#1486487, #1490607)
foreach ($messages as $mimeid) {
if (strpos($part->mime_id, $mimeid . '.') === 0) {
continue 2;
}
}
@ -1227,9 +1216,22 @@ function rcmail_write_inline_attachments(&$message)
{
global $RCMAIL, $COMPOSE;
$cid_map = array();
$cid_map = array();
$messages = array();
foreach ((array)$message->mime_parts as $pid => $part) {
if ($part->mimetype == 'message/rfc822') {
$messages[] = $part->mime_id;
}
if (($part->content_id || $part->content_location) && $part->filename) {
// skip attachments included in message/rfc822 attachment (#1486487, #1490607)
foreach ($messages as $mimeid) {
if (strpos($part->mime_id, $mimeid . '.') === 0) {
continue 2;
}
}
if ($attachment = rcmail_save_attachment($message, $pid)) {
$COMPOSE['attachments'][$attachment['id']] = $attachment;
$url = sprintf('%s&_id=%s&_action=display-attachment&_file=rcmfile%s',

@ -789,20 +789,15 @@ function rcmail_wash_html($html, $p, $cid_replaces)
*
* @param rcube_message_part Message part
* @param array Display parameters array
* @param string Part body
* @return string Formatted HTML string
*/
function rcmail_print_body($part, $p = array(), $body = null)
function rcmail_print_body($part, $p = array())
{
global $RCMAIL;
if ($body === null) {
$body = $part->body;
}
// trigger plugin hook
$data = $RCMAIL->plugins->exec_hook('message_part_before',
array('type' => $part->ctype_secondary, 'body' => $body, 'id' => $part->mime_id)
array('type' => $part->ctype_secondary, 'body' => $part->body, 'id' => $part->mime_id)
+ $p + array('safe' => false, 'plain' => false, 'inline_html' => true));
// convert html to text/plain
@ -1205,28 +1200,15 @@ function rcmail_message_body($attrib)
$part->body = $MESSAGE->get_part_content($part->mime_id);
}
$body = $part->body;
// extract headers from message/rfc822 parts
if ($part->mimetype == 'message/rfc822') {
$msgpart = rcube_mime::parse_message($part->body);
$body = rcube_charset::convert($msgpart->body, $msgpart->charset);
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
if ($body === false) {
if ($part->body === false) {
rcmail_message_error($MESSAGE->uid);
}
$plugin = $RCMAIL->plugins->exec_hook('message_body_prefix',
array('part' => $part, 'prefix' => ''));
$body = rcmail_print_body($part, array('safe' => $safe_mode, 'plain' => !$RCMAIL->config->get('prefer_html')), $body);
$body = rcmail_print_body($part, array('safe' => $safe_mode, 'plain' => !$RCMAIL->config->get('prefer_html')));
if ($part->ctype_secondary == 'html') {
$body = rcmail_html4inline($body, $attrib['id'], 'rcmBody', $attrs, $safe_mode);

Loading…
Cancel
Save