Skip to content

Commit fce3f80

Browse files
committed
fix: Always pass the correct sort timestamp to ChatId::set_protection() (#5088)
Before in some places it was correctly calculated by passing the "sent" timestamp to `calc_sort_timestamp()`, but in other places just the system time was used. In some complex scenarios like #5088 (restoration of a backup made before a contact verification) it led to wrong sort timestamps of protection messages and also messages following by them. But to reduce number of args passed to functions needing to calculate the sort timestamp, add message timestamps to `struct MimeMessage` which is anyway passed everywhere.
1 parent 2a0a51b commit fce3f80

File tree

5 files changed

+128
-73
lines changed

5 files changed

+128
-73
lines changed

src/chat.rs

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ use crate::mimefactory::MimeFactory;
3636
use crate::mimeparser::SystemMessage;
3737
use crate::param::{Param, Params};
3838
use crate::peerstate::Peerstate;
39-
use crate::receive_imf::ReceivedMsg;
39+
use crate::receive_imf::{calc_sort_timestamp, ReceivedMsg};
4040
use crate::smtp::send_msg_to_smtp;
4141
use crate::sql;
4242
use crate::stock_str;
@@ -578,7 +578,7 @@ impl ChatId {
578578
///
579579
/// `timestamp_sort` is used as the timestamp of the added message
580580
/// and should be the timestamp of the change happening.
581-
pub(crate) async fn set_protection(
581+
async fn set_protection_for_timestamp_sort(
582582
self,
583583
context: &Context,
584584
protect: ProtectionStatus,
@@ -600,13 +600,30 @@ impl ChatId {
600600
}
601601
}
602602

603+
/// Sets protection and sends or adds a message.
604+
///
605+
/// `timestamp_sent` is the "sent" timestamp of a message caused the protection state change.
606+
pub(crate) async fn set_protection(
607+
self,
608+
context: &Context,
609+
protect: ProtectionStatus,
610+
timestamp_sent: i64,
611+
contact_id: Option<ContactId>,
612+
) -> Result<()> {
613+
let sort_to_bottom = true;
614+
let ts = calc_sort_timestamp(context, timestamp_sent, self, sort_to_bottom, false).await?;
615+
self.set_protection_for_timestamp_sort(context, protect, ts, contact_id)
616+
.await
617+
}
618+
603619
/// Sets the 1:1 chat with the given address to ProtectionStatus::Protected,
604620
/// and posts a `SystemMessage::ChatProtectionEnabled` into it.
605621
///
606622
/// If necessary, creates a hidden chat for this.
607623
pub(crate) async fn set_protection_for_contact(
608624
context: &Context,
609625
contact_id: ContactId,
626+
timestamp: i64,
610627
) -> Result<()> {
611628
let chat_id = ChatId::create_for_contact_with_blocked(context, contact_id, Blocked::Yes)
612629
.await
@@ -615,7 +632,7 @@ impl ChatId {
615632
.set_protection(
616633
context,
617634
ProtectionStatus::Protected,
618-
smeared_time(context),
635+
timestamp,
619636
Some(contact_id),
620637
)
621638
.await?;
@@ -3258,7 +3275,7 @@ pub async fn create_group_chat(
32583275

32593276
if protect == ProtectionStatus::Protected {
32603277
chat_id
3261-
.set_protection(context, protect, timestamp, None)
3278+
.set_protection_for_timestamp_sort(context, protect, timestamp, None)
32623279
.await?;
32633280
}
32643281

src/mimeparser.rs

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
//! # MIME message parsing module.
22
3+
use std::cmp::min;
34
use std::collections::{HashMap, HashSet};
45
use std::future::Future;
56
use std::path::Path;
@@ -37,8 +38,8 @@ use crate::simplify::{simplify, SimplifiedText};
3738
use crate::stock_str;
3839
use crate::sync::SyncItems;
3940
use crate::tools::{
40-
create_smeared_timestamp, get_filemeta, parse_receive_headers, strip_rtlo_characters,
41-
truncate_by_lines,
41+
create_smeared_timestamp, get_filemeta, parse_receive_headers, smeared_time,
42+
strip_rtlo_characters, truncate_by_lines,
4243
};
4344
use crate::{location, tools};
4445

@@ -118,6 +119,12 @@ pub(crate) struct MimeMessage {
118119

119120
/// Whether the contact sending this should be marked as bot.
120121
pub(crate) is_bot: bool,
122+
123+
/// When the message was received, in secs since epoch.
124+
pub(crate) timestamp_rcvd: i64,
125+
/// Sender timestamp in secs since epoch. Allowed to be in the future due to unsynchronized
126+
/// clocks, but not too much.
127+
pub(crate) timestamp_sent: i64,
121128
}
122129

123130
#[derive(Debug, PartialEq)]
@@ -386,6 +393,12 @@ impl MimeMessage {
386393
// Auto-submitted is also set by holiday-notices so we also check `chat-version`
387394
let is_bot = headers.contains_key("auto-submitted") && headers.contains_key("chat-version");
388395

396+
let timestamp_rcvd = smeared_time(context);
397+
let timestamp_sent = headers
398+
.get(HeaderDef::Date.get_headername())
399+
.and_then(|value| mailparse::dateparse(value).ok())
400+
.map_or(timestamp_rcvd, |value| min(value, timestamp_rcvd + 60));
401+
389402
let mut parser = MimeMessage {
390403
parts: Vec::new(),
391404
headers,
@@ -415,6 +428,8 @@ impl MimeMessage {
415428
decoded_data: Vec::new(),
416429
hop_info,
417430
is_bot,
431+
timestamp_rcvd,
432+
timestamp_sent,
418433
};
419434

420435
match partial {
@@ -1630,21 +1645,15 @@ impl MimeMessage {
16301645
/// Handle reports
16311646
/// (MDNs = Message Disposition Notification, the message was read
16321647
/// and NDNs = Non delivery notification, the message could not be delivered)
1633-
pub async fn handle_reports(
1634-
&self,
1635-
context: &Context,
1636-
from_id: ContactId,
1637-
sent_timestamp: i64,
1638-
parts: &[Part],
1639-
) {
1648+
pub async fn handle_reports(&self, context: &Context, from_id: ContactId, parts: &[Part]) {
16401649
for report in &self.mdn_reports {
16411650
for original_message_id in report
16421651
.original_message_id
16431652
.iter()
16441653
.chain(&report.additional_message_ids)
16451654
{
16461655
if let Err(err) =
1647-
handle_mdn(context, from_id, original_message_id, sent_timestamp).await
1656+
handle_mdn(context, from_id, original_message_id, self.timestamp_sent).await
16481657
{
16491658
warn!(context, "Could not handle MDN: {err:#}.");
16501659
}

0 commit comments

Comments
 (0)