Skip to content

Commit 6836e82

Browse files
ivan-cxiequidoo
andauthored
fix!: use Viewtype::File for messages with invalid images, images of unknown size, huge images (#6825)
BREAKING CHANGE: messages with invalid images, images of unknown size, huge images, will have Viewtype::File After changing the logic of Viewtype selection, I had to fix 3 old tests that used invalid Base64 image data. Co-authored-by: iequidoo <117991069+iequidoo@users.noreply.github.com>
1 parent 416131b commit 6836e82

File tree

5 files changed

+121
-34
lines changed

5 files changed

+121
-34
lines changed

src/constants.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,9 @@ pub(crate) const WORSE_AVATAR_BYTES: usize = 20_000; // this also fits to Outloo
193193
pub const BALANCED_IMAGE_SIZE: u32 = 1280;
194194
pub const WORSE_IMAGE_SIZE: u32 = 640;
195195

196+
// Limit displayed images ~8.3 megapixels (3840 × 2160)
197+
pub const MAX_IMAGE_PIXELS: u32 = 8294400;
198+
196199
// Key for the folder configuration version (see below).
197200
pub(crate) const DC_FOLDERS_CONFIGURED_KEY: &str = "folders_configured";
198201
// this value can be increased if the folder configuration is changed and must be redone on next program start

src/mimeparser.rs

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1380,6 +1380,20 @@ impl MimeMessage {
13801380
} else {
13811381
Viewtype::File
13821382
}
1383+
} else if msg_type == Viewtype::Image
1384+
|| msg_type == Viewtype::Gif
1385+
|| msg_type == Viewtype::Sticker
1386+
{
1387+
match get_filemeta(decoded_data) {
1388+
// image size is known, not too big, keep msg_type:
1389+
Ok((width, height)) if width * height <= constants::MAX_IMAGE_PIXELS => {
1390+
part.param.set_i64(Param::Width, width.into());
1391+
part.param.set_i64(Param::Height, height.into());
1392+
msg_type
1393+
}
1394+
// image is too big or size is unknown, display as file:
1395+
_ => Viewtype::File,
1396+
}
13831397
} else {
13841398
msg_type
13851399
};
@@ -1400,13 +1414,6 @@ impl MimeMessage {
14001414
};
14011415
info!(context, "added blobfile: {:?}", blob.as_name());
14021416

1403-
if mime_type.type_() == mime::IMAGE {
1404-
if let Ok((width, height)) = get_filemeta(decoded_data) {
1405-
part.param.set_int(Param::Width, width as i32);
1406-
part.param.set_int(Param::Height, height as i32);
1407-
}
1408-
}
1409-
14101417
part.typ = msg_type;
14111418
part.org_filename = Some(filename.to_string());
14121419
part.mimetype = Some(mime_type);

src/mimeparser/mimeparser_tests.rs

Lines changed: 48 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -827,15 +827,7 @@ Content-Transfer-Encoding: base64
827827
Content-Disposition: inline;
828828
filename="JPEG_filename.jpg"
829829
830-
ISVb1L3m7z15Wy5w97a2cJg6W8P8YKOYfWn3PJ/UCSFcvCPtvBhcXieiN3M3ljguzG4XK7BnGgxG
831-
acAQdY8e0cWz1n+zKPNeNn4Iu3GXAXz4/IPksHk54inl1//0Lv8ggZjljfjnf0q1SPftYI7lpZWT
832-
/4aTCkimRrAIcwrQJPnZJRb7BPSC6kfn1QJHMv77mRMz2+4WbdfpyPQQ0CWLJsgVXtBsSMf2Awal
833-
n+zZzhGpXyCbWTEw1ccqZcK5KaiKNqWv51N4yVXw9dzJoCvxbYtCFGZZJdx7c+ObDotaF1/9KY4C
834-
xJjgK9/NgTXCZP1jYm0XIBnJsFSNg0pnMRETttTuGbOVi1/s/F1RGv5RNZsCUt21d9FhkWQQXsd2
835-
rOzDgTdag6BQCN3hSU9eKW/GhNBuMibRN9eS7Sm1y2qFU1HgGJBQfPPRPLKxXaNi++Zt0tnon2IU
836-
8pg5rP/IvStXYQNUQ9SiFdfAUkLU5b1j8ltnka8xl+oXsleSG44GPz6kM0RmwUrGkl4z/+NfHSsI
837-
K+TuvC7qOah0WLFhcsXWn2+dDV1bXuAeC769TkqkpHhdXfUHnVgK3Pv7u3rVPT5AMeFUGxRB2dP4
838-
CWt6wx7fiLp0qS9RrX75g6Gqw7nfCs6EcBERcIPt7DTe8VStJwf3LWqVwxl4gQl46yhfoqwEO+I=
830+
iVBORw0KGgoAAAANSUhEUgAAACAAAAAeCAAAAABoYUP1AAAAAXNSR0IArs4c6QAAAo1JREFUKJFdkdFuG0UUhr/szuxkxtlduzVx00jGUAhcI56CF0DiHXgFHqDiMfoCvAJC4gIJEBdVaZoGOY5dJ45r7zozmRlvzIVDm3Iu//PpP7/+s/OC/0+UREkEGZGr5N6mAX78MwISQEYJ6j6QYqZf7fzsYyRGJDISuQ9g6uMjW00WRCSRCP4DwNSEg496v828fC++B4yBGro7h+PliiiJHtR9B1vrmbtg359cOk+UqA8cDJm+eHu8yDfii6sAxK0u3hlsnPFn1WvT4XxYUqqtKu8cTMNKT8+nz3/aaWft3svKecBD/O9ETu2O//G7fXt5mHX2xwGP32aIEUNNvX/uh3z2pAkcKD+9XOLVNoMESw7YC+aPP8nqqSluyiuVaZRXCKLEQK3PxsP27UHe1lXV9eczCu2V8ippJA2gz+YTNTK9ttZOoYr+aeXwHp+k245cnFRNt1tmMJg3XV0dXQd3F5LcGn5fDnVQgwINRyFvtddnNmwBSW1qXfzNSDwoM+2A+aTbShfDd89Ka9ybiiLvGa33gK8THrWfVNUSSGLTALMRo/xBXnLbACu3QtRXY+sgkWnawKxCcLjPtr29gVZdPTidBUcSaXJeTfUL+mW4631Fmse+772xIGjSza/KTW/MYE/UCXPbEWs//Xxvqf8qZgYhG0jt8cnTnJpEgfDQ6rvE0n9tq66ICafil5OnOYt0hY94FUPoxI136uPpw4VIYNd+M5utrqvGpg0hc50bRl6BvLanX4pb/3347uWi/WgNHtYyyrdwszsX5fjZtwghy7C5sK2WgUoErcjIoEWr4fAHHhoRP+XZ86L/uMAarLFgsMBaAJhM8Ief9Ey7yHSmyXTp0GRoF7KQEdD/ArmtONKkgCleAAAAAElFTkSuQmCC
839831
840832
841833
----11019878869865180--
@@ -900,15 +892,7 @@ Content-ID: <part1.9DFA679B.52A88D69@example.org>
900892
Content-Disposition: inline;
901893
filename="1.png"
902894
903-
ISVb1L3m7z15Wy5w97a2cJg6W8P8YKOYfWn3PJ/UCSFcvCPtvBhcXieiN3M3ljguzG4XK7BnGgxG
904-
acAQdY8e0cWz1n+zKPNeNn4Iu3GXAXz4/IPksHk54inl1//0Lv8ggZjljfjnf0q1SPftYI7lpZWT
905-
/4aTCkimRrAIcwrQJPnZJRb7BPSC6kfn1QJHMv77mRMz2+4WbdfpyPQQ0CWLJsgVXtBsSMf2Awal
906-
n+zZzhGpXyCbWTEw1ccqZcK5KaiKNqWv51N4yVXw9dzJoCvxbYtCFGZZJdx7c+ObDotaF1/9KY4C
907-
xJjgK9/NgTXCZP1jYm0XIBnJsFSNg0pnMRETttTuGbOVi1/s/F1RGv5RNZsCUt21d9FhkWQQXsd2
908-
rOzDgTdag6BQCN3hSU9eKW/GhNBuMibRN9eS7Sm1y2qFU1HgGJBQfPPRPLKxXaNi++Zt0tnon2IU
909-
8pg5rP/IvStXYQNUQ9SiFdfAUkLU5b1j8ltnka8xl+oXsleSG44GPz6kM0RmwUrGkl4z/+NfHSsI
910-
K+TuvC7qOah0WLFhcsXWn2+dDV1bXuAeC769TkqkpHhdXfUHnVgK3Pv7u3rVPT5AMeFUGxRB2dP4
911-
CWt6wx7fiLp0qS9RrX75g6Gqw7nfCs6EcBERcIPt7DTe8VStJwf3LWqVwxl4gQl46yhfoqwEO+I=
895+
iVBORw0KGgoAAAANSUhEUgAAACAAAAAeCAAAAABoYUP1AAAAAXNSR0IArs4c6QAAAo1JREFUKJFdkdFuG0UUhr/szuxkxtlduzVx00jGUAhcI56CF0DiHXgFHqDiMfoCvAJC4gIJEBdVaZoGOY5dJ45r7zozmRlvzIVDm3Iu//PpP7/+s/OC/0+UREkEGZGr5N6mAX78MwISQEYJ6j6QYqZf7fzsYyRGJDISuQ9g6uMjW00WRCSRCP4DwNSEg496v828fC++B4yBGro7h+PliiiJHtR9B1vrmbtg359cOk+UqA8cDJm+eHu8yDfii6sAxK0u3hlsnPFn1WvT4XxYUqqtKu8cTMNKT8+nz3/aaWft3svKecBD/O9ETu2O//G7fXt5mHX2xwGP32aIEUNNvX/uh3z2pAkcKD+9XOLVNoMESw7YC+aPP8nqqSluyiuVaZRXCKLEQK3PxsP27UHe1lXV9eczCu2V8ippJA2gz+YTNTK9ttZOoYr+aeXwHp+k245cnFRNt1tmMJg3XV0dXQd3F5LcGn5fDnVQgwINRyFvtddnNmwBSW1qXfzNSDwoM+2A+aTbShfDd89Ka9ybiiLvGa33gK8THrWfVNUSSGLTALMRo/xBXnLbACu3QtRXY+sgkWnawKxCcLjPtr29gVZdPTidBUcSaXJeTfUL+mW4631Fmse+772xIGjSza/KTW/MYE/UCXPbEWs//Xxvqf8qZgYhG0jt8cnTnJpEgfDQ6rvE0n9tq66ICafil5OnOYt0hY94FUPoxI136uPpw4VIYNd+M5utrqvGpg0hc50bRl6BvLanX4pb/3347uWi/WgNHtYyyrdwszsX5fjZtwghy7C5sK2WgUoErcjIoEWr4fAHHhoRP+XZ86L/uMAarLFgsMBaAJhM8Ief9Ey7yHSmyXTp0GRoF7KQEdD/ArmtONKkgCleAAAAAElFTkSuQmCC
912896
--------------10CC6C2609EB38DA782C5CA9--
913897
914898
--------------779C1631600DF3DB8C02E53A--"#;
@@ -971,15 +955,7 @@ Content-Type: image/jpeg;
971955
Content-Transfer-Encoding: base64
972956
Content-ID: <image001.jpg@01D622B3.C9D8D750>
973957
974-
ISVb1L3m7z15Wy5w97a2cJg6W8P8YKOYfWn3PJ/UCSFcvCPtvBhcXieiN3M3ljguzG4XK7BnGgxG
975-
acAQdY8e0cWz1n+zKPNeNn4Iu3GXAXz4/IPksHk54inl1//0Lv8ggZjljfjnf0q1SPftYI7lpZWT
976-
/4aTCkimRrAIcwrQJPnZJRb7BPSC6kfn1QJHMv77mRMz2+4WbdfpyPQQ0CWLJsgVXtBsSMf2Awal
977-
n+zZzhGpXyCbWTEw1ccqZcK5KaiKNqWv51N4yVXw9dzJoCvxbYtCFGZZJdx7c+ObDotaF1/9KY4C
978-
xJjgK9/NgTXCZP1jYm0XIBnJsFSNg0pnMRETttTuGbOVi1/s/F1RGv5RNZsCUt21d9FhkWQQXsd2
979-
rOzDgTdag6BQCN3hSU9eKW/GhNBuMibRN9eS7Sm1y2qFU1HgGJBQfPPRPLKxXaNi++Zt0tnon2IU
980-
8pg5rP/IvStXYQNUQ9SiFdfAUkLU5b1j8ltnka8xl+oXsleSG44GPz6kM0RmwUrGkl4z/+NfHSsI
981-
K+TuvC7qOah0WLFhcsXWn2+dDV1bXuAeC769TkqkpHhdXfUHnVgK3Pv7u3rVPT5AMeFUGxRB2dP4
982-
CWt6wx7fiLp0qS9RrX75g6Gqw7nfCs6EcBERcIPt7DTe8VStJwf3LWqVwxl4gQl46yhfoqwEO+I=
958+
iVBORw0KGgoAAAANSUhEUgAAACAAAAAeCAAAAABoYUP1AAAAAXNSR0IArs4c6QAAAo1JREFUKJFdkdFuG0UUhr/szuxkxtlduzVx00jGUAhcI56CF0DiHXgFHqDiMfoCvAJC4gIJEBdVaZoGOY5dJ45r7zozmRlvzIVDm3Iu//PpP7/+s/OC/0+UREkEGZGr5N6mAX78MwISQEYJ6j6QYqZf7fzsYyRGJDISuQ9g6uMjW00WRCSRCP4DwNSEg496v828fC++B4yBGro7h+PliiiJHtR9B1vrmbtg359cOk+UqA8cDJm+eHu8yDfii6sAxK0u3hlsnPFn1WvT4XxYUqqtKu8cTMNKT8+nz3/aaWft3svKecBD/O9ETu2O//G7fXt5mHX2xwGP32aIEUNNvX/uh3z2pAkcKD+9XOLVNoMESw7YC+aPP8nqqSluyiuVaZRXCKLEQK3PxsP27UHe1lXV9eczCu2V8ippJA2gz+YTNTK9ttZOoYr+aeXwHp+k245cnFRNt1tmMJg3XV0dXQd3F5LcGn5fDnVQgwINRyFvtddnNmwBSW1qXfzNSDwoM+2A+aTbShfDd89Ka9ybiiLvGa33gK8THrWfVNUSSGLTALMRo/xBXnLbACu3QtRXY+sgkWnawKxCcLjPtr29gVZdPTidBUcSaXJeTfUL+mW4631Fmse+772xIGjSza/KTW/MYE/UCXPbEWs//Xxvqf8qZgYhG0jt8cnTnJpEgfDQ6rvE0n9tq66ICafil5OnOYt0hY94FUPoxI136uPpw4VIYNd+M5utrqvGpg0hc50bRl6BvLanX4pb/3347uWi/WgNHtYyyrdwszsX5fjZtwghy7C5sK2WgUoErcjIoEWr4fAHHhoRP+XZ86L/uMAarLFgsMBaAJhM8Ief9Ey7yHSmyXTp0GRoF7KQEdD/ArmtONKkgCleAAAAAElFTkSuQmCC
983959
984960
------=_NextPart_000_0003_01D622B3.CA753E60--
985961
"#;
@@ -2011,3 +1987,48 @@ async fn test_protected_date() -> Result<()> {
20111987
assert_eq!(alice_msg.get_timestamp(), bob_msg.get_timestamp());
20121988
Ok(())
20131989
}
1990+
1991+
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
1992+
async fn test_huge_image_becomes_file() -> Result<()> {
1993+
let t = TestContext::new_alice().await;
1994+
let msg_id = receive_imf(
1995+
&t,
1996+
include_bytes!("../../test-data/message/image_huge_36M.eml"),
1997+
false,
1998+
)
1999+
.await?
2000+
.unwrap()
2001+
.msg_ids[0];
2002+
let msg = Message::load_from_db(&t.ctx, msg_id).await.unwrap();
2003+
// Huge image should be treated as file:
2004+
assert_eq!(msg.viewtype, Viewtype::File);
2005+
assert!(msg.get_file(&t).is_some());
2006+
assert_eq!(msg.get_filename().unwrap(), "huge_image.png");
2007+
assert_eq!(msg.get_filemime().unwrap(), "image/png");
2008+
// File has no width or height
2009+
assert_eq!(msg.param.get_int(Param::Width).unwrap_or_default(), 0);
2010+
assert_eq!(msg.param.get_int(Param::Height).unwrap_or_default(), 0);
2011+
Ok(())
2012+
}
2013+
2014+
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
2015+
async fn test_4k_image_stays_image() -> Result<()> {
2016+
let t = TestContext::new_alice().await;
2017+
let msg_id = receive_imf(
2018+
&t,
2019+
include_bytes!("../../test-data/message/image_4k.eml"),
2020+
false,
2021+
)
2022+
.await?
2023+
.unwrap()
2024+
.msg_ids[0];
2025+
let msg = Message::load_from_db(&t.ctx, msg_id).await.unwrap();
2026+
// 4K image should be treated as image:
2027+
assert_eq!(msg.viewtype, Viewtype::Image);
2028+
assert!(msg.get_file(&t).is_some());
2029+
assert_eq!(msg.get_filename().unwrap(), "4k_image.png");
2030+
assert_eq!(msg.get_filemime().unwrap(), "image/png");
2031+
assert_eq!(msg.param.get_int(Param::Width).unwrap_or_default(), 3840);
2032+
assert_eq!(msg.param.get_int(Param::Height).unwrap_or_default(), 2160);
2033+
Ok(())
2034+
}

test-data/message/image_4k.eml

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
Received: (Postfix, from userid 1000); Mon, 4 Dec 2006 14:51:39 +0100 (CET)
2+
From: Test Sender <sender@testrun.org>
3+
Subject: Large image test
4+
To: alice@example.org
5+
Message-ID: <big-image-test@testrun.org>
6+
Date: Thu, 17 Dec 2020 15:38:45 +0100
7+
User-Agent: Test-Agent/1.0
8+
MIME-Version: 1.0
9+
Content-Type: multipart/mixed;
10+
boundary="------------BIG_IMAGE_BOUNDARY"
11+
Content-Language: en-US
12+
13+
This is a multi-part message in MIME format.
14+
--------------BIG_IMAGE_BOUNDARY
15+
Content-Type: text/plain; charset=utf-8
16+
Content-Transfer-Encoding: 7bit
17+
18+
Here is a 4k image
19+
20+
--------------BIG_IMAGE_BOUNDARY
21+
Content-Type: image/png;
22+
name="4k_image.png"
23+
Content-Transfer-Encoding: base64
24+
Content-Disposition: attachment;
25+
filename="4k_image.png"
26+
27+
iVBORw0KGgoAAAANSUhEUgAADwAAAAhwCAIAAAAf3FwlAAAAEElEQVR4nAEFAPr/AP////8AAAAFCeiupAAAAABJRU5ErkJggg==
28+
--------------BIG_IMAGE_BOUNDARY--

test-data/message/image_huge_36M.eml

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
Received: (Postfix, from userid 1000); Mon, 4 Dec 2006 14:51:39 +0100 (CET)
2+
From: Test Sender <sender@testrun.org>
3+
Subject: Large image test
4+
To: alice@example.org
5+
Message-ID: <huge-image-test@testrun.org>
6+
Date: Thu, 17 Dec 2020 15:38:45 +0100
7+
User-Agent: Test-Agent/1.0
8+
MIME-Version: 1.0
9+
Content-Type: multipart/mixed;
10+
boundary="------------HUGE_IMAGE_BOUNDARY"
11+
Content-Language: en-US
12+
13+
This is a multi-part message in MIME format.
14+
--------------HUGE_IMAGE_BOUNDARY
15+
Content-Type: text/plain; charset=utf-8
16+
Content-Transfer-Encoding: 7bit
17+
18+
Here is a huge image
19+
20+
--------------HUGE_IMAGE_BOUNDARY
21+
Content-Type: image/png;
22+
name="huge_image.png"
23+
Content-Transfer-Encoding: base64
24+
Content-Disposition: attachment;
25+
filename="huge_image.png"
26+
27+
iVBORw0KGgoAAAANSUhEUgAAF3AAABdwCAIAAABsNhAUAAAAEElEQVR4nAEFAPr/AP////8AAAAFCeiupAAAAABJRU5ErkJggg==
28+
--------------HUGE_IMAGE_BOUNDARY--

0 commit comments

Comments
 (0)