From bd99e977529a7c6f03d7e4023fa75c3b3a1618d8 Mon Sep 17 00:00:00 2001 From: iequidoo Date: Thu, 18 Sep 2025 09:45:10 -0300 Subject: [PATCH 1/2] fix: Don't send self-avatar in unencrypted messages (#7136) We don't display avatars for address-contacts, so sending avatars w/o encryption is not useful and causes e.g. Outlook to reject a message with a big header, see https://support.delta.chat/t/invalid-mime-content-single-text-value-size-32822-exceeded-allowed-maximum-32768-for-the-chat-user-avatar-header/4067. --- src/mimefactory.rs | 6 ++- src/mimefactory/mimefactory_tests.rs | 74 +--------------------------- 2 files changed, 6 insertions(+), 74 deletions(-) diff --git a/src/mimefactory.rs b/src/mimefactory.rs index 68271afb46..00865cc900 100644 --- a/src/mimefactory.rs +++ b/src/mimefactory.rs @@ -464,7 +464,11 @@ impl MimeFactory { .unwrap_or_default(), false => "".to_string(), }; - let attach_selfavatar = Self::should_attach_selfavatar(context, &msg).await; + // We don't display avatars for address-contacts, so sending avatars w/o encryption is not + // useful and causes e.g. Outlook to reject a message with a big header, see + // https://support.delta.chat/t/invalid-mime-content-single-text-value-size-32822-exceeded-allowed-maximum-32768-for-the-chat-user-avatar-header/4067. + let attach_selfavatar = + Self::should_attach_selfavatar(context, &msg).await && encryption_pubkeys.is_some(); ensure_and_debug_assert!( member_timestamps.is_empty() diff --git a/src/mimefactory/mimefactory_tests.rs b/src/mimefactory/mimefactory_tests.rs index 62d02eb9ec..8892138c7c 100644 --- a/src/mimefactory/mimefactory_tests.rs +++ b/src/mimefactory/mimefactory_tests.rs @@ -592,26 +592,6 @@ async fn test_selfavatar_unencrypted() -> anyhow::Result<()> { assert_eq!(outer.match_indices("Autocrypt:").count(), 1); assert_eq!(outer.match_indices("Chat-User-Avatar:").count(), 0); - assert_eq!(inner.match_indices("text/plain").count(), 1); - assert_eq!(inner.match_indices("Message-ID:").count(), 1); - assert_eq!(inner.match_indices("Chat-User-Avatar:").count(), 1); - assert_eq!(inner.match_indices("Subject:").count(), 0); - - assert_eq!(body.match_indices("this is the text!").count(), 1); - - // if another message is sent, that one must not contain the avatar - let sent_msg = t.send_msg(chat.id, &mut msg).await; - let mut payload = sent_msg.payload().splitn(3, "\r\n\r\n"); - let outer = payload.next().unwrap(); - let inner = payload.next().unwrap(); - let body = payload.next().unwrap(); - - assert_eq!(outer.match_indices("multipart/mixed").count(), 1); - assert_eq!(outer.match_indices("Message-ID:").count(), 1); - assert_eq!(outer.match_indices("Subject:").count(), 1); - assert_eq!(outer.match_indices("Autocrypt:").count(), 1); - assert_eq!(outer.match_indices("Chat-User-Avatar:").count(), 0); - assert_eq!(inner.match_indices("text/plain").count(), 1); assert_eq!(inner.match_indices("Message-ID:").count(), 1); assert_eq!(inner.match_indices("Chat-User-Avatar:").count(), 0); @@ -670,7 +650,7 @@ async fn test_selfavatar_unencrypted_signed() { assert_eq!(part.match_indices("text/plain").count(), 1); assert_eq!(part.match_indices("From:").count(), 0); assert_eq!(part.match_indices("Message-ID:").count(), 1); - assert_eq!(part.match_indices("Chat-User-Avatar:").count(), 1); + assert_eq!(part.match_indices("Chat-User-Avatar:").count(), 0); assert_eq!(part.match_indices("Subject:").count(), 0); let body = payload.next().unwrap(); @@ -684,58 +664,6 @@ async fn test_selfavatar_unencrypted_signed() { .unwrap(); let alice_contact = Contact::get_by_id(&bob.ctx, alice_id).await.unwrap(); assert_eq!(alice_contact.is_key_contact(), false); - assert!( - alice_contact - .get_profile_image(&bob.ctx) - .await - .unwrap() - .is_some() - ); - - // if another message is sent, that one must not contain the avatar - let mut msg = Message::new_text("this is the text!".to_string()); - let sent_msg = t.send_msg(chat.id, &mut msg).await; - let mut payload = sent_msg.payload().splitn(4, "\r\n\r\n"); - - let part = payload.next().unwrap(); - assert_eq!(part.match_indices("multipart/signed").count(), 1); - assert_eq!(part.match_indices("From:").count(), 1); - assert_eq!(part.match_indices("Message-ID:").count(), 1); - assert_eq!(part.match_indices("Subject:").count(), 1); - assert_eq!(part.match_indices("Autocrypt:").count(), 1); - assert_eq!(part.match_indices("Chat-User-Avatar:").count(), 0); - - let part = payload.next().unwrap(); - assert_eq!( - part.match_indices("multipart/mixed; protected-headers=\"v1\"") - .count(), - 1 - ); - assert_eq!(part.match_indices("From:").count(), 1); - assert_eq!(part.match_indices("Message-ID:").count(), 0); - assert_eq!(part.match_indices("Subject:").count(), 1); - assert_eq!(part.match_indices("Autocrypt:").count(), 1); - assert_eq!(part.match_indices("Chat-User-Avatar:").count(), 0); - - let part = payload.next().unwrap(); - assert_eq!(part.match_indices("text/plain").count(), 1); - assert_eq!(body.match_indices("From:").count(), 0); - assert_eq!(part.match_indices("Message-ID:").count(), 1); - assert_eq!(part.match_indices("Chat-User-Avatar:").count(), 0); - assert_eq!(part.match_indices("Subject:").count(), 0); - - let body = payload.next().unwrap(); - assert_eq!(body.match_indices("this is the text!").count(), 1); - - bob.recv_msg(&sent_msg).await; - let alice_contact = Contact::get_by_id(&bob.ctx, alice_id).await.unwrap(); - assert!( - alice_contact - .get_profile_image(&bob.ctx) - .await - .unwrap() - .is_some() - ); } /// Test that removed member address does not go into the `To:` field. From bac45da37f96c48b06c1f3988bef5a7fc34e5998 Mon Sep 17 00:00:00 2001 From: iequidoo Date: Fri, 19 Sep 2025 02:14:20 -0300 Subject: [PATCH 2/2] feat: Don't send Chat-Group-Avatar header in unencrypted groups `chat::set_chat_profile_image()` already checks that the group has grpid, still it makes sense to check that a message is encrypted when sending, in case if the chat has a profile image in the db for some reason. --- src/mimefactory.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/mimefactory.rs b/src/mimefactory.rs index 00865cc900..da8270dfdb 100644 --- a/src/mimefactory.rs +++ b/src/mimefactory.rs @@ -1586,7 +1586,7 @@ impl MimeFactory { "Chat-Content", mail_builder::headers::text::Text::new("group-avatar-changed").into(), )); - if grpimage.is_none() { + if grpimage.is_none() && is_encrypted { headers.push(( "Chat-Group-Avatar", mail_builder::headers::raw::Raw::new("0").into(), @@ -1713,7 +1713,9 @@ impl MimeFactory { _ => {} } - if let Some(grpimage) = grpimage { + if let Some(grpimage) = grpimage + && is_encrypted + { info!(context, "setting group image '{}'", grpimage); let avatar = build_avatar_file(context, grpimage) .await