From 34b3f99820d0c215b52b95384a895a8333456143 Mon Sep 17 00:00:00 2001 From: iequidoo Date: Thu, 23 Apr 2026 10:47:27 -0300 Subject: [PATCH] fix: Don't receive message if a deletion request was received before (#8143) There's no check for `from_id` so another group member can delete the message, but this can only happen in case of message reordering and the problem already exists for usual messages, so we may ignore it and overall a group represents a scope of trust. --- src/chat/chat_tests.rs | 7 ++++++- src/message.rs | 2 +- src/receive_imf.rs | 15 +++++++++------ 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/src/chat/chat_tests.rs b/src/chat/chat_tests.rs index 36cf276d7..13dd0b4b9 100644 --- a/src/chat/chat_tests.rs +++ b/src/chat/chat_tests.rs @@ -5822,7 +5822,7 @@ async fn test_send_delete_request() -> Result<()> { let sent2 = alice.pop_sent_msg().await; assert_eq!(alice_chat.id.get_msg_cnt(alice).await?, E2EE_INFO_MSGS + 1); - // Bob receives both messages and has nothing the end + // Bob receives both messages and has nothing at the end let bob_msg = bob.recv_msg(&sent1).await; assert_eq!(bob_msg.text, "wtf"); assert_eq!(bob_msg.chat_id.get_msg_cnt(bob).await?, E2EE_INFO_MSGS + 2); @@ -5830,6 +5830,11 @@ async fn test_send_delete_request() -> Result<()> { bob.recv_msg_opt(&sent2).await; assert_eq!(bob_msg.chat_id.get_msg_cnt(bob).await?, E2EE_INFO_MSGS + 1); + // ... even if he receives messages in reverse order. + let bob2 = &tcm.bob().await; + bob2.recv_msg_opt(&sent2).await; + assert!(bob2.recv_msg_opt(&sent1).await.is_none()); + // Alice has another device, and there is also nothing at the end let alice2 = &tcm.alice().await; alice2.recv_msg(&sent0).await; diff --git a/src/message.rs b/src/message.rs index d40de7299..a77f928a1 100644 --- a/src/message.rs +++ b/src/message.rs @@ -529,7 +529,7 @@ impl Message { FROM msgs m LEFT JOIN chats c ON c.id=m.chat_id LEFT JOIN msgs_mdns mdns ON mdns.msg_id=m.id - WHERE m.id=? AND chat_id!=3 + WHERE m.id=? AND chat_id!=3 -- DC_CHAT_ID_TRASH LIMIT 1", (id,), |row| { diff --git a/src/receive_imf.rs b/src/receive_imf.rs index 0415d76b4..8381b06fe 100644 --- a/src/receive_imf.rs +++ b/src/receive_imf.rs @@ -534,15 +534,14 @@ pub(crate) async fn receive_imf_inner( replace_msg_id = None; replace_chat_id = None; } else if let Some(old_msg_id) = message::rfc724_mid_exists(context, rfc724_mid).await? { - // This code handles the download of old partial download stub messages - // It will be removed after a transitioning period, - // after we have released a few versions with pre-messages replace_msg_id = Some(old_msg_id); replace_chat_id = if let Some(msg) = Message::load_from_db_optional(context, old_msg_id) .await? .filter(|msg| msg.download_state() != DownloadState::Done) { - // The message was partially downloaded before. + // This code handles the download of old partial download stub messages + // It will be removed after a transitioning period, + // after we have released a few versions with pre-messages match mime_parser.pre_message { PreMessageMode::Post | PreMessageMode::None => { info!(context, "Message already partly in DB, replacing."); @@ -554,8 +553,10 @@ pub(crate) async fn receive_imf_inner( } } } else { - // The message was already fully downloaded - // or cannot be loaded because it is deleted. + info!( + context, + "Message {rfc724_mid} is fully downloaded or deleted." + ); None }; } else { @@ -2481,6 +2482,7 @@ async fn handle_edit_delete( let rfc724_mid_vec: Vec<&str> = rfc724_mid_list.split_whitespace().collect(); for rfc724_mid in rfc724_mid_vec { + let rfc724_mid = rfc724_mid.trim_start_matches('<').trim_end_matches('>'); if let Some(msg_id) = message::rfc724_mid_exists(context, rfc724_mid).await? { if let Some(msg) = Message::load_from_db_optional(context, msg_id).await? { if msg.from_id == from_id { @@ -2495,6 +2497,7 @@ async fn handle_edit_delete( } } else { warn!(context, "Delete message: {rfc724_mid:?} not found."); + insert_tombstone(context, rfc724_mid).await?; } } message::delete_msgs_locally_done(context, &msg_ids, modified_chat_ids).await?;