mirror of
https://github.com/chatmail/core.git
synced 2026-05-24 09:16:32 +03:00
fix: do not fail to receive post-message with status updates for deleted webxdc
receive_imf should not fail in this case, but trash the post-message and updates. The problem with previously used message::rfc724_mid_exists check was that rfc724_mid_exists may return a trashed message.
This commit is contained in:
@@ -602,6 +602,35 @@ impl Message {
|
|||||||
Ok(msg)
|
Ok(msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Loads the message with given Message-ID from the database.
|
||||||
|
///
|
||||||
|
/// Cannot return a trashed message.
|
||||||
|
pub async fn load_by_rfc724_mid_optional(
|
||||||
|
context: &Context,
|
||||||
|
rfc724_mid: &str,
|
||||||
|
) -> Result<Option<Message>> {
|
||||||
|
if let Some(msg_id) = context
|
||||||
|
.sql
|
||||||
|
.query_row_optional(
|
||||||
|
"SELECT id FROM msgs WHERE rfc724_mid=? AND chat_id != ?",
|
||||||
|
(rfc724_mid, DC_CHAT_ID_TRASH),
|
||||||
|
|row| {
|
||||||
|
let msg_id: MsgId = row.get(0)?;
|
||||||
|
Ok(msg_id)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.await?
|
||||||
|
{
|
||||||
|
// Non-trashed message exists, load it.
|
||||||
|
let msg = Self::load_from_db(context, msg_id)
|
||||||
|
.await
|
||||||
|
.context("Failed to load the message we just checked exists")?;
|
||||||
|
Ok(Some(msg))
|
||||||
|
} else {
|
||||||
|
Ok(None)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns additional text which is appended to the message's text field
|
/// Returns additional text which is appended to the message's text field
|
||||||
/// when it is loaded from the database.
|
/// when it is loaded from the database.
|
||||||
/// Currently this is used to add infomation to pre-messages of what the download will be and how large it is
|
/// Currently this is used to add infomation to pre-messages of what the download will be and how large it is
|
||||||
|
|||||||
@@ -835,21 +835,16 @@ UPDATE config SET value=? WHERE keyname='configured_addr' AND value!=?1
|
|||||||
{
|
{
|
||||||
can_info_msg = false;
|
can_info_msg = false;
|
||||||
if mime_parser.pre_message == PreMessageMode::Post
|
if mime_parser.pre_message == PreMessageMode::Post
|
||||||
&& let Some(msg_id) = message::rfc724_mid_exists(context, rfc724_mid_orig).await?
|
&& let Some(msg) =
|
||||||
|
Message::load_by_rfc724_mid_optional(context, rfc724_mid_orig).await?
|
||||||
{
|
{
|
||||||
// The messsage is a post-message and pre-message exists.
|
// The messsage is a post-message and pre-message exists.
|
||||||
// Assign status update to existing message because just received post-message will be trashed.
|
// Assign status update to existing message because just received post-message will be trashed.
|
||||||
Some(
|
Some(msg)
|
||||||
Message::load_from_db(context, msg_id)
|
|
||||||
.await
|
|
||||||
.context("Failed to load webxdc instance that we just checked exists")?,
|
|
||||||
)
|
|
||||||
} else {
|
} else {
|
||||||
Some(
|
Message::load_from_db_optional(context, insert_msg_id)
|
||||||
Message::load_from_db(context, insert_msg_id)
|
|
||||||
.await
|
.await
|
||||||
.context("Failed to load just created webxdc instance")?,
|
.context("Failed to load just created webxdc instance")?
|
||||||
)
|
|
||||||
}
|
}
|
||||||
} else if let Some(field) = mime_parser.get_header(HeaderDef::InReplyTo) {
|
} else if let Some(field) = mime_parser.get_header(HeaderDef::InReplyTo) {
|
||||||
if let Some(instance) =
|
if let Some(instance) =
|
||||||
|
|||||||
@@ -565,6 +565,45 @@ async fn test_webxdc_updates_in_post_message_after_pre_message() -> Result<()> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||||
|
async fn test_webxdc_updates_in_post_message_after_deleted_pre_message() -> Result<()> {
|
||||||
|
let mut tcm = TestContextManager::new();
|
||||||
|
let alice = &tcm.alice().await;
|
||||||
|
let bob = &tcm.bob().await;
|
||||||
|
|
||||||
|
let alice_chat_id = alice.create_chat_id(bob).await;
|
||||||
|
let big_webxdc_app = big_webxdc_app().await?;
|
||||||
|
|
||||||
|
let mut alice_instance = Message::new(Viewtype::Webxdc);
|
||||||
|
alice_instance.set_file_from_bytes(alice, "test.xdc", &big_webxdc_app, None)?;
|
||||||
|
alice_instance.set_text("Test".to_string());
|
||||||
|
alice_chat_id
|
||||||
|
.set_draft(alice, Some(&mut alice_instance))
|
||||||
|
.await?;
|
||||||
|
alice
|
||||||
|
.send_webxdc_status_update(alice_instance.id, r#"{"payload":42, "info":"i"}"#)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
send_msg(alice, alice_chat_id, &mut alice_instance).await?;
|
||||||
|
let post_message = alice.pop_sent_msg().await;
|
||||||
|
let pre_message = alice.pop_sent_msg().await;
|
||||||
|
|
||||||
|
let bob_instance = bob.recv_msg(&pre_message).await;
|
||||||
|
assert_eq!(bob_instance.download_state, DownloadState::Available);
|
||||||
|
delete_msgs(bob, &[bob_instance.id]).await?;
|
||||||
|
|
||||||
|
bob.recv_msg_trash(&post_message).await;
|
||||||
|
|
||||||
|
// Deleted message stays trashed because of a tombstone.
|
||||||
|
assert!(
|
||||||
|
Message::load_from_db_optional(bob, bob_instance.id)
|
||||||
|
.await?
|
||||||
|
.is_none()
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
/// Tests receiving of a large webxdc post-message with updates attached
|
/// Tests receiving of a large webxdc post-message with updates attached
|
||||||
/// to the the .xdc post-message when pre-message arrives later.
|
/// to the the .xdc post-message when pre-message arrives later.
|
||||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||||
|
|||||||
Reference in New Issue
Block a user