1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
|
From: Aleksander Machniak <alec@alec.pl>
Date: Sun, 2 Jun 2024 15:13:42 +0200
Subject: Fix fatal error when parsing some TNEF attachments
Origin: https://github.com/roundcube/roundcubemail/commit/22d403d5fdea1846319389d3d65ef60726434712
Bug: https://github.com/roundcube/roundcubemail/issues/9462
---
program/lib/Roundcube/rcube_tnef_decoder.php | 3 +-
tests/Framework/Message.php | 87 ++++++++++++++++++++++++++++
2 files changed, 89 insertions(+), 1 deletion(-)
diff --git a/program/lib/Roundcube/rcube_tnef_decoder.php b/program/lib/Roundcube/rcube_tnef_decoder.php
index 092e6c5..8308303 100644
--- a/program/lib/Roundcube/rcube_tnef_decoder.php
+++ b/program/lib/Roundcube/rcube_tnef_decoder.php
@@ -162,7 +162,7 @@ class rcube_tnef_decoder
}
// Return the message body as HTML
- if ($message && $as_html) {
+ if ($as_html) {
// HTML body
if (!empty($message['size']) && $message['subtype'] == 'html') {
$message = $message['stream'];
@@ -180,6 +180,7 @@ class rcube_tnef_decoder
}
catch (Exception $e) {
// ignore the body
+ $message = null;
rcube::raise_error([
'file' => __FILE__,
'line' => __LINE__,
diff --git a/tests/Framework/Message.php b/tests/Framework/Message.php
index 16b4661..3e40e93 100644
--- a/tests/Framework/Message.php
+++ b/tests/Framework/Message.php
@@ -18,4 +18,91 @@ class Framework_Message extends PHPUnit\Framework\TestCase
$this->assertSame('test', $result);
}
+
+ /**
+ * Test tnef_decode() method
+ */
+ public function test_tnef_decode()
+ {
+ $message = new rcube_message_test(123);
+ $part = new rcube_message_part();
+ $part->mime_id = 1;
+
+ $message->set_part_body(1, '');
+ $result = $message->tnef_decode($part);
+
+ $this->assertSame([], $result);
+
+ $message->set_part_body(1, file_get_contents(TESTS_DIR . 'src/body.tnef'));
+ $result = $message->tnef_decode($part);
+
+ $this->assertCount(1, $result);
+ $this->assertInstanceOf('rcube_message_part', $result[0]);
+ $this->assertSame('winmail.1.html', $result[0]->mime_id);
+ $this->assertSame('text/html', $result[0]->mimetype);
+ $this->assertSame(5360, $result[0]->size);
+ $this->assertStringStartsWith('<!DOCTYPE HTML', $result[0]->body);
+ $this->assertSame([], $result[0]->parts);
+
+ $message->set_part_body(1, file_get_contents(TESTS_DIR . 'src/one-file.tnef'));
+ $result = $message->tnef_decode($part);
+
+ $this->assertCount(1, $result);
+ $this->assertInstanceOf('rcube_message_part', $result[0]);
+ $this->assertSame('winmail.1.0', $result[0]->mime_id);
+ $this->assertSame('application/octet-stream', $result[0]->mimetype);
+ $this->assertSame(244, $result[0]->size);
+ $this->assertStringContainsString(' Authors of', $result[0]->body);
+ $this->assertSame([], $result[0]->parts);
+ }
+
+ /**
+ * Test uu_decode() method
+ */
+ public function test_uu_decode()
+ {
+ $message = new rcube_message_test(123);
+ $part = new rcube_message_part();
+ $part->mime_id = 1;
+
+ $message->set_part_body(1, '');
+ $result = $message->uu_decode($part);
+
+ $this->assertSame([], $result);
+
+ $content = "begin 644 /dev/stdout\n" . convert_uuencode('test') . "end";
+ $message->set_part_body(1, $content);
+
+ $result = $message->uu_decode($part);
+
+ $this->assertCount(1, $result);
+ $this->assertInstanceOf('rcube_message_part', $result[0]);
+ $this->assertSame('uu.1.0', $result[0]->mime_id);
+ $this->assertSame('text/plain', $result[0]->mimetype);
+ $this->assertSame(4, $result[0]->size);
+ $this->assertSame('test', $result[0]->body);
+ $this->assertSame([], $result[0]->parts);
+ }
+}
+
+/**
+ * rcube_message wrapper for easier testing (without accessing IMAP)
+ */
+class rcube_message_test extends rcube_message
+{
+ private $part_bodies = [];
+
+ public function __construct($uid, $folder = null, $is_safe = false)
+ {
+ }
+
+ public function get_part_body($mime_id, $formatted = false, $max_bytes = 0, $mode = null)
+ {
+ return $this->part_bodies[$mime_id] ?? null;
+ }
+
+ public function set_part_body($mime_id, $body)
+ {
+ $this->part_bodies[$mime_id] = $body;
+ }
}
|