mirror of
https://github.com/chatmail/core.git
synced 2026-05-08 09:26:29 +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 std::ptr;
|
||||||
|
|
||||||
use itertools::join;
|
use itertools::join;
|
||||||
use libc::{free, strcmp, strlen};
|
use libc::{free, strcmp};
|
||||||
use mmime::clist::*;
|
use mmime::clist::*;
|
||||||
use mmime::mailimf::types::*;
|
use mmime::mailimf::types::*;
|
||||||
use mmime::mailimf::*;
|
|
||||||
use mmime::mailmime::content::*;
|
use mmime::mailmime::content::*;
|
||||||
use mmime::mailmime::types::*;
|
use mmime::mailmime::types::*;
|
||||||
use mmime::mailmime::*;
|
use mmime::mailmime::*;
|
||||||
@@ -819,24 +818,16 @@ unsafe fn handle_reports(
|
|||||||
&& !of_org_msgid.is_null()
|
&& !of_org_msgid.is_null()
|
||||||
&& !(*of_org_msgid).fld_value.is_null()
|
&& !(*of_org_msgid).fld_value.is_null()
|
||||||
{
|
{
|
||||||
let mut rfc724_mid_0 = std::ptr::null_mut();
|
if let Ok(rfc724_mid) = wrapmime::parse_message_id(as_str(
|
||||||
dummy = 0;
|
|
||||||
|
|
||||||
if mailimf_msg_id_parse(
|
|
||||||
(*of_org_msgid).fld_value,
|
(*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 chat_id_0 = 0;
|
||||||
let mut msg_id = 0;
|
let mut msg_id = 0;
|
||||||
|
|
||||||
if message::mdn_from_ext(
|
if message::mdn_from_ext(
|
||||||
context,
|
context,
|
||||||
from_id,
|
from_id,
|
||||||
as_str(rfc724_mid_0),
|
&rfc724_mid,
|
||||||
sent_timestamp,
|
sent_timestamp,
|
||||||
&mut chat_id_0,
|
&mut chat_id_0,
|
||||||
&mut msg_id,
|
&mut msg_id,
|
||||||
@@ -844,7 +835,6 @@ unsafe fn handle_reports(
|
|||||||
rr_event_to_send.push((chat_id_0, msg_id));
|
rr_event_to_send.push((chat_id_0, msg_id));
|
||||||
}
|
}
|
||||||
mdn_consumed = (msg_id != 0) as libc::c_int;
|
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::constants::*;
|
||||||
use crate::context::Context;
|
use crate::context::Context;
|
||||||
use crate::dc_receive_imf::dc_receive_imf;
|
use crate::dc_receive_imf::dc_receive_imf;
|
||||||
|
use crate::error::Error;
|
||||||
use crate::events::Event;
|
use crate::events::Event;
|
||||||
use crate::job::{job_add, Action};
|
use crate::job::{job_add, Action};
|
||||||
use crate::login_param::LoginParam;
|
use crate::login_param::LoginParam;
|
||||||
use crate::message::{self, update_msg_move_state, update_server_uid};
|
use crate::message::{self, update_msg_move_state, update_server_uid};
|
||||||
use crate::oauth2::dc_get_oauth2_access_token;
|
use crate::oauth2::dc_get_oauth2_access_token;
|
||||||
use crate::param::Params;
|
use crate::param::Params;
|
||||||
|
use crate::wrapmime;
|
||||||
|
|
||||||
const DC_IMAP_SEEN: usize = 0x0001;
|
const DC_IMAP_SEEN: usize = 0x0001;
|
||||||
|
|
||||||
@@ -815,11 +817,7 @@ impl Imap {
|
|||||||
if cur_uid > last_seen_uid {
|
if cur_uid > last_seen_uid {
|
||||||
read_cnt += 1;
|
read_cnt += 1;
|
||||||
|
|
||||||
let message_id = msg
|
let message_id = prefetch_get_message_id(msg).unwrap_or_default();
|
||||||
.envelope()
|
|
||||||
.expect("missing envelope")
|
|
||||||
.message_id
|
|
||||||
.expect("missing message id");
|
|
||||||
|
|
||||||
if !precheck_imf(context, &message_id, folder.as_ref(), cur_uid) {
|
if !precheck_imf(context, &message_id, folder.as_ref(), cur_uid) {
|
||||||
// check passed, go fetch the rest
|
// check passed, go fetch the rest
|
||||||
@@ -1322,25 +1320,31 @@ impl Imap {
|
|||||||
if let Some(ref mut session) = &mut *self.session.lock().unwrap() {
|
if let Some(ref mut session) = &mut *self.session.lock().unwrap() {
|
||||||
match session.uid_fetch(set, PREFETCH_FLAGS) {
|
match session.uid_fetch(set, PREFETCH_FLAGS) {
|
||||||
Ok(msgs) => {
|
Ok(msgs) => {
|
||||||
if msgs.is_empty()
|
if msgs.is_empty() {
|
||||||
|| msgs
|
|
||||||
.first()
|
|
||||||
.unwrap()
|
|
||||||
.envelope()
|
|
||||||
.expect("missing envelope")
|
|
||||||
.message_id
|
|
||||||
.expect("missing message id")
|
|
||||||
!= message_id.as_ref()
|
|
||||||
{
|
|
||||||
warn!(
|
warn!(
|
||||||
context,
|
context,
|
||||||
"Cannot delete on IMAP, {}/{} does not match {}.",
|
"Cannot delete on IMAP, {}/{}: message-id gone '{}'",
|
||||||
folder.as_ref(),
|
folder.as_ref(),
|
||||||
server_uid,
|
server_uid,
|
||||||
message_id.as_ref(),
|
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) => {
|
Err(err) => {
|
||||||
eprintln!("fetch error: {:?}", err);
|
eprintln!("fetch error: {:?}", err);
|
||||||
@@ -1555,3 +1559,8 @@ fn precheck_imf(context: &Context, rfc724_mid: &str, server_folder: &str, server
|
|||||||
false
|
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 crate::error::Error;
|
||||||
use mmime::clist::*;
|
use mmime::clist::*;
|
||||||
// use mmime::display::*;
|
// use mmime::display::*;
|
||||||
|
use mmime::mailimf::mailimf_msg_id_parse;
|
||||||
use mmime::mailimf::types::*;
|
use mmime::mailimf::types::*;
|
||||||
use mmime::mailimf::types_helper::*;
|
use mmime::mailimf::types_helper::*;
|
||||||
use mmime::mailmime::content::*;
|
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(
|
pub fn get_autocrypt_mime(
|
||||||
mime_undetermined: *mut Mailmime,
|
mime_undetermined: *mut Mailmime,
|
||||||
) -> Result<(*mut Mailmime, *mut Mailmime), Error> {
|
) -> Result<(*mut Mailmime, *mut Mailmime), Error> {
|
||||||
@@ -518,4 +536,16 @@ mod tests {
|
|||||||
new_content_type("application/pgp-encrypted").unwrap()
|
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