From e8e0c683691018629d93fbf686f44c02d8ffdaee Mon Sep 17 00:00:00 2001 From: Aleksander Machniak Date: Sun, 16 Jun 2024 12:47:56 +0200 Subject: [PATCH] Fix decoding mail parts with multiple base64-encoded text blocks (#9290) --- CHANGELOG.md | 1 + program/lib/Roundcube/rcube_imap_generic.php | 9 ++++++++- tests/Framework/ImapGeneric.php | 20 ++++++++++++++++++++ 3 files changed, 29 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 07940159754..994109fe956 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ - Fix newmail_notifier notification focus in Chrome (#9467) - Fix fatal error when parsing some TNEF attachments (#9462) - Fix double scrollbar when composing a mail with many plain text lines (#7760) +- Fix decoding mail parts with multiple base64-encoded text blocks (#9290) ## Release 1.6.7 diff --git a/program/lib/Roundcube/rcube_imap_generic.php b/program/lib/Roundcube/rcube_imap_generic.php index 2c68aeea43b..8b73fbc0d0b 100644 --- a/program/lib/Roundcube/rcube_imap_generic.php +++ b/program/lib/Roundcube/rcube_imap_generic.php @@ -3049,7 +3049,14 @@ protected static function decodeContent($chunk, $mode, $is_last = false, &$prev $prev = ''; } - return base64_decode($chunk); + // There might be multiple base64 blocks in a single message part, + // we have to pass them separately to base64_decode() (#9290) + $result = ''; + foreach (preg_split('|=+|', $chunk, -1, \PREG_SPLIT_NO_EMPTY) as $_chunk) { + $result .= base64_decode($_chunk); + } + + return $result; } // QUOTED-PRINTABLE diff --git a/tests/Framework/ImapGeneric.php b/tests/Framework/ImapGeneric.php index 82c8b98399f..6724c30097a 100644 --- a/tests/Framework/ImapGeneric.php +++ b/tests/Framework/ImapGeneric.php @@ -151,6 +151,26 @@ function test_decode_content_base64() $this->runDecodeContent($content, $encoded, 1, 6000); } + /** + * Test for decodeContent() with base64 encoding (multiple bodies) + */ + public function test_decode_content_base64_multiple() + { + $expected = $content = str_repeat('a', 100); + $encoded = chunk_split(base64_encode($content), 72, "\r\n"); + + $expected .= ($content = str_repeat('b', 101)); + $encoded .= chunk_split(base64_encode($content), 72, "\r\n"); + + $expected .= ($content = str_repeat('c', 102)); + $encoded .= chunk_split(base64_encode($content), 72, "\r\n"); + + $expected .= ($content = str_repeat('d', 103)); + $encoded .= chunk_split(base64_encode($content), 72, "\r\n"); + + $this->runDecodeContent($expected, $encoded, 1); + } + /** * Test for decodeContent() with quoted-printable encoding */