properly parse message ids in imap prefetch

This commit is contained in:
holger krekel
2019-10-01 11:45:37 +02:00
parent 9c077c98cd
commit f0a7bdb6d6
3 changed files with 60 additions and 31 deletions

View File

@@ -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());
}
}
}

View File

@@ -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)
}

View File

@@ -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"
);
}
}