mirror of
https://github.com/chatmail/core.git
synced 2026-04-17 13:36:30 +03:00
properly parse message ids in imap prefetch
This commit is contained in:
@@ -2,10 +2,9 @@ use std::ffi::CString;
|
||||
use std::ptr;
|
||||
|
||||
use itertools::join;
|
||||
use libc::{free, strcmp, strlen};
|
||||
use libc::{free, strcmp};
|
||||
use mmime::clist::*;
|
||||
use mmime::mailimf::types::*;
|
||||
use mmime::mailimf::*;
|
||||
use mmime::mailmime::content::*;
|
||||
use mmime::mailmime::types::*;
|
||||
use mmime::mailmime::*;
|
||||
@@ -819,24 +818,16 @@ unsafe fn handle_reports(
|
||||
&& !of_org_msgid.is_null()
|
||||
&& !(*of_org_msgid).fld_value.is_null()
|
||||
{
|
||||
let mut rfc724_mid_0 = std::ptr::null_mut();
|
||||
dummy = 0;
|
||||
|
||||
if mailimf_msg_id_parse(
|
||||
if let Ok(rfc724_mid) = wrapmime::parse_message_id(as_str(
|
||||
(*of_org_msgid).fld_value,
|
||||
strlen((*of_org_msgid).fld_value),
|
||||
&mut dummy,
|
||||
&mut rfc724_mid_0,
|
||||
) == MAIL_NO_ERROR as libc::c_int
|
||||
&& !rfc724_mid_0.is_null()
|
||||
{
|
||||
)) {
|
||||
let mut chat_id_0 = 0;
|
||||
let mut msg_id = 0;
|
||||
|
||||
if message::mdn_from_ext(
|
||||
context,
|
||||
from_id,
|
||||
as_str(rfc724_mid_0),
|
||||
&rfc724_mid,
|
||||
sent_timestamp,
|
||||
&mut chat_id_0,
|
||||
&mut msg_id,
|
||||
@@ -844,7 +835,6 @@ unsafe fn handle_reports(
|
||||
rr_event_to_send.push((chat_id_0, msg_id));
|
||||
}
|
||||
mdn_consumed = (msg_id != 0) as libc::c_int;
|
||||
free(rfc724_mid_0.cast());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
43
src/imap.rs
43
src/imap.rs
@@ -8,12 +8,14 @@ use std::time::{Duration, SystemTime};
|
||||
use crate::constants::*;
|
||||
use crate::context::Context;
|
||||
use crate::dc_receive_imf::dc_receive_imf;
|
||||
use crate::error::Error;
|
||||
use crate::events::Event;
|
||||
use crate::job::{job_add, Action};
|
||||
use crate::login_param::LoginParam;
|
||||
use crate::message::{self, update_msg_move_state, update_server_uid};
|
||||
use crate::oauth2::dc_get_oauth2_access_token;
|
||||
use crate::param::Params;
|
||||
use crate::wrapmime;
|
||||
|
||||
const DC_IMAP_SEEN: usize = 0x0001;
|
||||
|
||||
@@ -815,11 +817,7 @@ impl Imap {
|
||||
if cur_uid > last_seen_uid {
|
||||
read_cnt += 1;
|
||||
|
||||
let message_id = msg
|
||||
.envelope()
|
||||
.expect("missing envelope")
|
||||
.message_id
|
||||
.expect("missing message id");
|
||||
let message_id = prefetch_get_message_id(msg).unwrap_or_default();
|
||||
|
||||
if !precheck_imf(context, &message_id, folder.as_ref(), cur_uid) {
|
||||
// check passed, go fetch the rest
|
||||
@@ -1322,25 +1320,31 @@ impl Imap {
|
||||
if let Some(ref mut session) = &mut *self.session.lock().unwrap() {
|
||||
match session.uid_fetch(set, PREFETCH_FLAGS) {
|
||||
Ok(msgs) => {
|
||||
if msgs.is_empty()
|
||||
|| msgs
|
||||
.first()
|
||||
.unwrap()
|
||||
.envelope()
|
||||
.expect("missing envelope")
|
||||
.message_id
|
||||
.expect("missing message id")
|
||||
!= message_id.as_ref()
|
||||
{
|
||||
if msgs.is_empty() {
|
||||
warn!(
|
||||
context,
|
||||
"Cannot delete on IMAP, {}/{} does not match {}.",
|
||||
"Cannot delete on IMAP, {}/{}: message-id gone '{}'",
|
||||
folder.as_ref(),
|
||||
server_uid,
|
||||
message_id.as_ref(),
|
||||
);
|
||||
*server_uid = 0;
|
||||
} else {
|
||||
let remote_message_id =
|
||||
prefetch_get_message_id(msgs.first().unwrap())
|
||||
.unwrap_or_default();
|
||||
|
||||
if remote_message_id != message_id.as_ref() {
|
||||
warn!(
|
||||
context,
|
||||
"Cannot delete on IMAP, {}/{}: remote message-id '{}' != '{}'",
|
||||
folder.as_ref(),
|
||||
server_uid,
|
||||
remote_message_id,
|
||||
message_id.as_ref(),
|
||||
);
|
||||
}
|
||||
}
|
||||
*server_uid = 0;
|
||||
}
|
||||
Err(err) => {
|
||||
eprintln!("fetch error: {:?}", err);
|
||||
@@ -1555,3 +1559,8 @@ fn precheck_imf(context: &Context, rfc724_mid: &str, server_folder: &str, server
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
fn prefetch_get_message_id(prefetch_msg: &imap::types::Fetch) -> Result<String, Error> {
|
||||
let message_id = prefetch_msg.envelope().unwrap().message_id.unwrap();
|
||||
wrapmime::parse_message_id(&message_id)
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ use crate::dc_tools::*;
|
||||
use crate::error::Error;
|
||||
use mmime::clist::*;
|
||||
// use mmime::display::*;
|
||||
use mmime::mailimf::mailimf_msg_id_parse;
|
||||
use mmime::mailimf::types::*;
|
||||
use mmime::mailimf::types_helper::*;
|
||||
use mmime::mailmime::content::*;
|
||||
@@ -48,6 +49,23 @@ pub fn get_ct_subtype(mime: *mut Mailmime) -> Option<String> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn parse_message_id(message_id: &str) -> Result<String, Error> {
|
||||
let mut dummy = 0;
|
||||
let c_message_id = CString::new(message_id).unwrap();
|
||||
let c_ptr = c_message_id.as_ptr();
|
||||
let mut rfc724_mid_c = std::ptr::null_mut();
|
||||
if unsafe { mailimf_msg_id_parse(c_ptr, libc::strlen(c_ptr), &mut dummy, &mut rfc724_mid_c) }
|
||||
== MAIL_NO_ERROR as libc::c_int
|
||||
&& !rfc724_mid_c.is_null()
|
||||
{
|
||||
let res = to_string_lossy(rfc724_mid_c);
|
||||
unsafe { libc::free(rfc724_mid_c.cast()) };
|
||||
Ok(res)
|
||||
} else {
|
||||
bail!("could not parse message_id: {}", message_id);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_autocrypt_mime(
|
||||
mime_undetermined: *mut Mailmime,
|
||||
) -> Result<(*mut Mailmime, *mut Mailmime), Error> {
|
||||
@@ -518,4 +536,16 @@ mod tests {
|
||||
new_content_type("application/pgp-encrypted").unwrap()
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_message_id() {
|
||||
assert_eq!(
|
||||
parse_message_id("Mr.PRUe8HJBoaO.3whNvLCMFU0@testrun.org").unwrap(),
|
||||
"Mr.PRUe8HJBoaO.3whNvLCMFU0@testrun.org"
|
||||
);
|
||||
assert_eq!(
|
||||
parse_message_id("<Mr.PRUe8HJBoaO.3whNvLCMFU0@testrun.org>").unwrap(),
|
||||
"Mr.PRUe8HJBoaO.3whNvLCMFU0@testrun.org"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user