diff options
author | Aleksander Machniak <alec@alec.pl> | 2021-07-01 15:28:37 +0300 |
---|---|---|
committer | Aleksander Machniak <alec@alec.pl> | 2021-07-01 15:30:18 +0300 |
commit | b44acbecbf80019b33ff3a31493d07d5036bf190 (patch) | |
tree | f0b85ba1c6fc8dc462b5abab94a40c2b481f25b6 | |
parent | b15ff4f064a217c3af116a16e85d44cb76e560ce (diff) |
Fix displaying HTML body with inline images encapsulated using TNEF format (winmail.dat)
-rw-r--r-- | CHANGELOG | 1 | ||||
-rw-r--r-- | program/lib/Roundcube/rcube_message.php | 58 | ||||
-rw-r--r-- | program/lib/Roundcube/rcube_tnef_decoder.php | 4 |
3 files changed, 61 insertions, 2 deletions
@@ -6,6 +6,7 @@ CHANGELOG Roundcube Webmail - Fix bug causing some HTML message content to be not centered in Elastic skin (#7911) - Fix bug where consecutive LDAP searches could return wrong results (#8064) - Fix bug where plus characters in attachment filename could have been ignored (#8074) +- Fix displaying HTML body with inline images encapsulated using TNEF format (winmail.dat) RELEASE 1.4.11 -------------- diff --git a/program/lib/Roundcube/rcube_message.php b/program/lib/Roundcube/rcube_message.php index ea368f4f7..01b0e6dec 100644 --- a/program/lib/Roundcube/rcube_message.php +++ b/program/lib/Roundcube/rcube_message.php @@ -381,7 +381,13 @@ class rcube_message $last = $parent->real_mimetype ?: $parent->mimetype; if (!preg_match('/^multipart\/(alternative|related|signed|encrypted|mixed)$/', $last) - || ($last == 'multipart/mixed' && $parent_depth < $max_delta)) { + || ($last == 'multipart/mixed' && $parent_depth < $max_delta) + ) { + // The HTML body part extracted from a winmail.dat attachment part + if (strpos($part->mime_id, 'winmail.') === 0) { + return true; + } + continue 2; } } @@ -822,9 +828,33 @@ class rcube_message // part is Microsoft Outlook TNEF (winmail.dat) else if ($part_mimetype == 'application/ms-tnef' && $this->tnef_decode) { $tnef_parts = (array) $this->tnef_decode($mail_part); + $tnef_body = ''; + foreach ($tnef_parts as $tpart) { $this->mime_parts[$tpart->mime_id] = $tpart; - $this->add_part($tpart, 'attachment'); + + if (strpos($tpart->mime_id, '.html')) { + $tnef_body = $tpart->body; + if ($this->opt['prefer_html']) { + $tpart->type = 'content'; + + // Reset type on the plain text part that usually is added to winmail.dat messages + // (on the same level in the structure as the attachment itself) + $level = count(explode('.', $mail_part->mime_id)); + foreach ($this->parts as $p) { + if ($p->type == 'content' && $p->mimetype == 'text/plain' + && count(explode('.', $p->mime_id)) == $level + ) { + $p->type = null; + } + } + } + $this->add_part($tpart); + } + else { + $inline = !empty($tpart->content_id) && strpos($tnef_body, "cid:{$tpart->content_id}") !== false; + $this->add_part($tpart, $inline ? 'inline' : 'attachment'); + } } // add winmail.dat to the list if it's content is unknown @@ -1005,6 +1035,26 @@ class rcube_message unset($body); + // HTML body + if ( + !empty($tnef_arr['message']) + && !empty($tnef_arr['message']['size']) + && $tnef_arr['message']['subtype'] == 'html' + ) { + $tpart = new rcube_message_part; + + $tpart->encoding = 'stream'; + $tpart->ctype_primary = 'text'; + $tpart->ctype_secondary = 'html'; + $tpart->mimetype = 'text/html'; + $tpart->mime_id = 'winmail.' . $part->mime_id . '.html'; + $tpart->size = $tnef_arr['message']['size']; + $tpart->body = $tnef_arr['message']['stream']; + + $parts[] = $tpart; + } + + // Attachments foreach ($tnef_arr['attachments'] as $pid => $winatt) { $tpart = new rcube_message_part; @@ -1017,6 +1067,10 @@ class rcube_message $tpart->size = $winatt['size']; $tpart->body = $winatt['stream']; + if (!empty($winatt['content-id'])) { + $tpart->content_id = $winatt['content-id']; + } + $parts[] = $tpart; unset($tnef_arr[$pid]); } diff --git a/program/lib/Roundcube/rcube_tnef_decoder.php b/program/lib/Roundcube/rcube_tnef_decoder.php index c11bdb456..1ac2527e3 100644 --- a/program/lib/Roundcube/rcube_tnef_decoder.php +++ b/program/lib/Roundcube/rcube_tnef_decoder.php @@ -362,6 +362,10 @@ class rcube_tnef_decoder $result['subtype'] = $value[1]; break; + case self::MAPI_ATTACH_CONTENT_ID: + $result['content-id'] = $value; + break; + case self::MAPI_ATTACH_DATA: $this->_getx($value, 16); $att = new rcube_tnef_decoder; |