From 498979c6083e082213874fdf099f1f542a8f8d1a Mon Sep 17 00:00:00 2001 From: link2xt Date: Wed, 15 Jan 2025 16:20:56 +0000 Subject: [PATCH] fix: trash no-op addition messages This partially restores the fix from c9cf2b7f2edfff3e83889e84ed38dd76ee22b457 that was removed during the addition of new group consistency at de63527d940b0304d3095b4cf940eec4ef02c28d but only for "Member added" messages. Multiple "Member added" messages happen when the same QR code is processed multiple times by multiple devices. --- src/chat.rs | 4 ++-- src/receive_imf.rs | 13 +++++++++++-- src/receive_imf/tests.rs | 26 ++++++++++++++++++++++++++ 3 files changed, 39 insertions(+), 4 deletions(-) diff --git a/src/chat.rs b/src/chat.rs index f8bfb62b1..163ce9bb9 100644 --- a/src/chat.rs +++ b/src/chat.rs @@ -5301,8 +5301,8 @@ mod tests { // Bob receives the add and deletion messages out of order let bob = TestContext::new_bob().await; bob.recv_msg(&add1).await; - bob.recv_msg(&add3).await; - let bob_chat_id = bob.recv_msg(&add2).await.chat_id; + let bob_chat_id = bob.recv_msg(&add3).await.chat_id; + bob.recv_msg_trash(&add2).await; // No-op addition message is trashed. assert_eq!(get_chat_contacts(&bob, bob_chat_id).await?.len(), 4); bob.recv_msg(&remove2).await; diff --git a/src/receive_imf.rs b/src/receive_imf.rs index d2f8e69f9..894e2ba2a 100644 --- a/src/receive_imf.rs +++ b/src/receive_imf.rs @@ -1528,6 +1528,9 @@ async fn add_parts( let mut txt_raw = "".to_string(); let (msg, typ): (&str, Viewtype) = if let Some(better_msg) = &better_msg { + if better_msg.is_empty() && is_partial_download.is_none() { + chat_id = DC_CHAT_ID_TRASH; + } (better_msg, Viewtype::Text) } else { (&part.msg, part.typ) @@ -2197,7 +2200,8 @@ async fn update_chats_contacts_timestamps( /// Apply group member list, name, avatar and protection status changes from the MIME message. /// /// Returns `Vec` of group changes messages and, optionally, a better message to replace the -/// original system message. +/// original system message. If the better message is empty, the original system message +/// should be trashed. /// /// * `to_ids` - contents of the `To` and `Cc` headers. /// * `past_ids` - contents of the `Chat-Group-Past-Members` header. @@ -2394,7 +2398,12 @@ async fn apply_group_changes( } if let Some(added_id) = added_id { - added_ids.remove(&added_id); + if !added_ids.remove(&added_id) && !self_added { + // No-op "Member added" message. + // + // Trash it. + better_msg = Some(String::new()); + } } if let Some(removed_id) = removed_id { removed_ids.remove(&removed_id); diff --git a/src/receive_imf/tests.rs b/src/receive_imf/tests.rs index 60bbeb680..76cef08e6 100644 --- a/src/receive_imf/tests.rs +++ b/src/receive_imf/tests.rs @@ -5049,6 +5049,32 @@ async fn test_unarchive_on_member_removal() -> Result<()> { Ok(()) } +#[tokio::test(flavor = "multi_thread", worker_threads = 2)] +async fn test_no_op_member_added_is_trash() -> Result<()> { + let mut tcm = TestContextManager::new(); + let alice = &tcm.alice().await; + let bob = &tcm.bob().await; + let alice_chat_id = alice + .create_group_with_members(ProtectionStatus::Unprotected, "foos", &[bob]) + .await; + send_text_msg(alice, alice_chat_id, "populate".to_string()).await?; + let msg = alice.pop_sent_msg().await; + bob.recv_msg(&msg).await; + let bob_chat_id = bob.get_last_msg().await.chat_id; + bob_chat_id.accept(bob).await?; + + let fiona_id = Contact::create(alice, "", "fiona@example.net").await?; + add_contact_to_chat(alice, alice_chat_id, fiona_id).await?; + let msg = alice.pop_sent_msg().await; + + let fiona_id = Contact::create(bob, "", "fiona@example.net").await?; + add_contact_to_chat(bob, bob_chat_id, fiona_id).await?; + bob.recv_msg_trash(&msg).await; + let contacts = get_chat_contacts(bob, bob_chat_id).await?; + assert_eq!(contacts.len(), 3); + Ok(()) +} + #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn test_forged_from() -> Result<()> { let mut tcm = TestContextManager::new();