From 74d8368525f707ef68c8c96acd028e024a91b256 Mon Sep 17 00:00:00 2001 From: holger krekel Date: Sun, 22 Sep 2019 03:56:27 +0200 Subject: [PATCH] rustify references, in_reply_to, mimefactory's recipients_{addr,names} --- src/chat.rs | 4 +- src/dc_mimefactory.rs | 229 ++++++++++++++++-------------------------- src/dc_strencode.rs | 22 ++-- src/dc_tools.rs | 180 +++++++++------------------------ src/e2ee.rs | 12 +-- src/job.rs | 39 ++----- 6 files changed, 160 insertions(+), 326 deletions(-) diff --git a/src/chat.rs b/src/chat.rs index 361c9cb53..cc231eb08 100644 --- a/src/chat.rs +++ b/src/chat.rs @@ -784,7 +784,7 @@ pub fn send_msg(context: &Context, chat_id: u32, msg: &mut Message) -> Result { pub from_addr: String, pub from_displayname: String, pub selfstatus: String, - pub recipients_names: *mut clist, - pub recipients_addr: *mut clist, + pub recipients_names: Vec, + pub recipients_addr: Vec, pub timestamp: i64, pub rfc724_mid: String, pub loaded: Loaded, pub msg: Message, pub chat: Option, pub increation: bool, - pub in_reply_to: *mut libc::c_char, - pub references: *mut libc::c_char, + pub in_reply_to: String, + pub references: String, pub req_mdn: bool, pub out: *mut MMAPString, pub out_encrypted: bool, @@ -65,16 +65,16 @@ impl<'a> MimeFactory<'a> { from_displayname: cget(&context, "displayname").unwrap_or_default(), selfstatus: cget(&context, "selfstatus") .unwrap_or_else(|| context.stock_str(StockMessage::StatusLine).to_string()), - recipients_names: clist_new(), - recipients_addr: clist_new(), + recipients_names: Vec::with_capacity(5), + recipients_addr: Vec::with_capacity(5), timestamp: 0, rfc724_mid: String::default(), loaded: Loaded::Nothing, msg, chat: None, increation: false, - in_reply_to: ptr::null_mut(), - references: ptr::null_mut(), + in_reply_to: String::default(), + references: String::default(), req_mdn: false, out: ptr::null_mut(), out_encrypted: false, @@ -88,17 +88,6 @@ impl<'a> MimeFactory<'a> { impl<'a> Drop for MimeFactory<'a> { fn drop(&mut self) { unsafe { - if !self.recipients_names.is_null() { - clist_free_content(self.recipients_names); - clist_free(self.recipients_names); - } - if !self.recipients_addr.is_null() { - clist_free_content(self.recipients_addr); - clist_free(self.recipients_addr); - } - - free(self.in_reply_to as *mut libc::c_void); - free(self.references as *mut libc::c_void); if !self.out.is_null() { mmap_string_free(self.out); } @@ -106,10 +95,7 @@ impl<'a> Drop for MimeFactory<'a> { } } -pub unsafe fn dc_mimefactory_load_msg( - context: &Context, - msg_id: u32, -) -> Result { +pub fn dc_mimefactory_load_msg(context: &Context, msg_id: u32) -> Result { ensure!(msg_id > DC_CHAT_ID_LAST_SPECIAL, "Invalid chat id"); let msg = Message::load_from_db(context, msg_id)?; @@ -121,16 +107,10 @@ pub unsafe fn dc_mimefactory_load_msg( let chat = factory.chat.as_ref().unwrap(); if chat.is_self_talk() { - clist_insert_after( - factory.recipients_names, - (*factory.recipients_names).last, - factory.from_displayname.strdup().cast(), - ); - clist_insert_after( - factory.recipients_addr, - (*factory.recipients_addr).last, - factory.from_addr.strdup().cast(), - ); + factory + .recipients_names + .push(factory.from_displayname.to_string()); + factory.recipients_addr.push(factory.from_addr.to_string()); } else { context .sql @@ -148,22 +128,9 @@ pub unsafe fn dc_mimefactory_load_msg( |rows| { for row in rows { let (authname, addr) = row?; - let addr_c = addr.strdup(); - if !clist_search_string_nocase(factory.recipients_addr, addr_c) { - clist_insert_after( - factory.recipients_names, - (*factory.recipients_names).last, - if !authname.is_empty() { - authname.strdup() - } else { - std::ptr::null_mut() - } as *mut libc::c_void, - ); - clist_insert_after( - factory.recipients_addr, - (*factory.recipients_addr).last, - addr_c as *mut libc::c_void, - ); + if !vec_contains_lowercase(&factory.recipients_addr, &addr) { + factory.recipients_addr.push(addr); + factory.recipients_names.push(authname); } } Ok(()) @@ -176,7 +143,6 @@ pub unsafe fn dc_mimefactory_load_msg( if command == SystemMessage::MemberRemovedFromGroup { let email_to_remove = msg.param.get(Param::Arg).unwrap_or_default(); - let email_to_remove_c = email_to_remove.strdup(); let self_addr = context .sql @@ -184,17 +150,9 @@ pub unsafe fn dc_mimefactory_load_msg( .unwrap_or_default(); if !email_to_remove.is_empty() && email_to_remove != self_addr { - if !clist_search_string_nocase(factory.recipients_addr, email_to_remove_c) { - clist_insert_after( - factory.recipients_names, - (*factory.recipients_names).last, - ptr::null_mut(), - ); - clist_insert_after( - factory.recipients_addr, - (*factory.recipients_addr).last, - email_to_remove_c as *mut libc::c_void, - ); + if !vec_contains_lowercase(&factory.recipients_addr, &email_to_remove) { + factory.recipients_names.push("".to_string()); + factory.recipients_addr.push(email_to_remove.to_string()); } } } @@ -220,8 +178,8 @@ pub unsafe fn dc_mimefactory_load_msg( ); match row { Ok((in_reply_to, references)) => { - factory.in_reply_to = in_reply_to.strdup(); - factory.references = references.strdup(); + factory.in_reply_to = in_reply_to; + factory.references = references; } Err(err) => { error!( @@ -239,7 +197,7 @@ pub unsafe fn dc_mimefactory_load_msg( Ok(factory) } -pub unsafe fn dc_mimefactory_load_mdn<'a>( +pub fn dc_mimefactory_load_mdn<'a>( context: &'a Context, msg_id: u32, ) -> Result { @@ -266,20 +224,10 @@ pub unsafe fn dc_mimefactory_load_mdn<'a>( "Invalid chat id" ); - clist_insert_after( - factory.recipients_names, - (*factory.recipients_names).last, - (if !contact.get_authname().is_empty() { - contact.get_authname().strdup() - } else { - ptr::null_mut() - }) as *mut libc::c_void, - ); - clist_insert_after( - factory.recipients_addr, - (*factory.recipients_addr).last, - contact.get_addr().strdup() as *mut libc::c_void, - ); + factory + .recipients_names + .push(contact.get_authname().to_string()); + factory.recipients_addr.push(contact.get_addr().to_string()); factory.timestamp = dc_create_smeared_timestamp(factory.context); factory.rfc724_mid = dc_create_outgoing_rfc724_mid(None, &factory.from_addr); factory.loaded = Loaded::MDN; @@ -287,6 +235,8 @@ pub unsafe fn dc_mimefactory_load_mdn<'a>( Ok(factory) } +// XXX push down unsafe to only guard mailimf_* operations + pub unsafe fn dc_mimefactory_render( context: &Context, factory: &mut MimeFactory, @@ -299,7 +249,7 @@ pub unsafe fn dc_mimefactory_render( from, mailimf_mailbox_new( if !factory.from_displayname.is_empty() { - dc_encode_header_words(&factory.from_displayname) + dc_encode_header_words(&factory.from_displayname).strdup() } else { ptr::null_mut() }, @@ -307,47 +257,38 @@ pub unsafe fn dc_mimefactory_render( ), ); let mut to: *mut mailimf_address_list = ptr::null_mut(); - if !factory.recipients_names.is_null() - && !factory.recipients_addr.is_null() - && (*factory.recipients_addr).count > 0 - { - let name_iter = (*factory.recipients_names).into_iter(); - let addr_iter = (*factory.recipients_addr).into_iter(); + if !factory.recipients_names.is_empty() && !factory.recipients_addr.is_empty() { to = mailimf_address_list_new_empty(); + let name_iter = factory.recipients_names.iter(); + let addr_iter = factory.recipients_addr.iter(); for (name, addr) in name_iter.zip(addr_iter) { - let name = name as *const libc::c_char; - let addr = addr as *const libc::c_char; mailimf_address_list_add( to, mailimf_address_new( MAILIMF_ADDRESS_MAILBOX as libc::c_int, mailimf_mailbox_new( - if !name.is_null() { - dc_encode_header_words(as_str(name)) + if !name.is_empty() { + dc_encode_header_words(&name).strdup() } else { ptr::null_mut() }, - dc_strdup(addr), + addr.strdup(), ), ptr::null_mut(), ), ); } } - let mut references_list: *mut clist = ptr::null_mut(); - if !factory.references.is_null() && 0 != *factory.references.offset(0isize) as libc::c_int { - references_list = dc_str_to_clist( - factory.references, - b" \x00" as *const u8 as *const libc::c_char, - ) - } - let mut in_reply_to_list: *mut clist = ptr::null_mut(); - if !factory.in_reply_to.is_null() && 0 != *factory.in_reply_to.offset(0isize) as libc::c_int { - in_reply_to_list = dc_str_to_clist( - factory.in_reply_to, - b" \x00" as *const u8 as *const libc::c_char, - ) - } + let references_list = if !factory.references.is_empty() { + dc_str_to_clist(&factory.references, " ") + } else { + ptr::null_mut() + }; + let in_reply_to_list = if !factory.in_reply_to.is_empty() { + dc_str_to_clist(&factory.in_reply_to, " ") + } else { + ptr::null_mut() + }; let imf_fields = mailimf_fields_new_with_data_all( mailimf_get_date(factory.timestamp as i64), from, @@ -432,18 +373,8 @@ pub unsafe fn dc_mimefactory_render( if chat.typ == Chattype::Group || chat.typ == Chattype::VerifiedGroup { add_mailimf_field(imf_fields, "Chat-Group-ID", &chat.grpid); - // we can't use add_mailimf_field() because - // dc_encode_header_words returns char* and most of its call sites - // use it rather directly to pass something to the - // low-level mailimf_* API. - let res = mailimf_fields_add( - imf_fields, - mailimf_field_new_custom( - "Chat-Group-Name".strdup(), - dc_encode_header_words(&chat.name), - ), - ); - assert!(res == MAILIMF_NO_ERROR as i32); + let encoded = dc_encode_header_words(&chat.name); + add_mailimf_field(imf_fields, "Chat-Group-Name", &encoded); match command { SystemMessage::MemberRemovedFromGroup => { @@ -742,7 +673,6 @@ pub unsafe fn dc_mimefactory_render( } }; - let subject = mailimf_subject_new(dc_encode_header_words(subject_str)); mailimf_fields_add( imf_fields, mailimf_field_new( @@ -765,7 +695,7 @@ pub unsafe fn dc_mimefactory_render( ptr::null_mut(), ptr::null_mut(), ptr::null_mut(), - subject, + mailimf_subject_new(dc_encode_header_words(subject_str).strdup()), ptr::null_mut(), ptr::null_mut(), ptr::null_mut(), @@ -775,7 +705,7 @@ pub unsafe fn dc_mimefactory_render( if force_plaintext != DC_FP_NO_AUTOCRYPT_HEADER { e2ee_helper.encrypt( factory.context, - factory.recipients_addr, + &factory.recipients_addr, force_plaintext == DC_FP_ADD_AUTOCRYPT_HEADER, e2ee_guaranteed, min_verified, @@ -823,37 +753,44 @@ fn get_subject( } } -pub unsafe fn add_mailimf_field(fields: *mut mailimf_fields, name: &str, value: &str) { - let field = mailimf_field_new_custom(name.strdup(), value.strdup()); - let res = mailimf_fields_add(fields, field); - assert!( - res as u32 == MAILIMF_NO_ERROR, - "could not create mailimf field" - ); +pub fn add_mailimf_field(fields: *mut mailimf_fields, name: &str, value: &str) { + unsafe { + let field = mailimf_field_new_custom(name.strdup(), value.strdup()); + let res = mailimf_fields_add(fields, field); + assert!( + res as u32 == MAILIMF_NO_ERROR, + "could not create mailimf field" + ); + } } -unsafe fn build_body_text(text: &str) -> *mut mailmime { +fn build_body_text(text: &str) -> *mut mailmime { let mime_fields: *mut mailmime_fields; let message_part: *mut mailmime; let content: *mut mailmime_content; - content = mailmime_content_new_with_str(b"text/plain\x00" as *const u8 as *const libc::c_char); - clist_insert_after( - (*content).ct_parameters, - (*(*content).ct_parameters).last, - mailmime_param_new_with_data( - b"charset\x00" as *const u8 as *const libc::c_char as *mut libc::c_char, - b"utf-8\x00" as *const u8 as *const libc::c_char as *mut libc::c_char, - ) as *mut libc::c_void, - ); - mime_fields = mailmime_fields_new_encoding(MAILMIME_MECHANISM_8BIT as libc::c_int); - message_part = mailmime_new_empty(content, mime_fields); + unsafe { + content = + mailmime_content_new_with_str(b"text/plain\x00" as *const u8 as *const libc::c_char); + clist_insert_after( + (*content).ct_parameters, + (*(*content).ct_parameters).last, + mailmime_param_new_with_data( + b"charset\x00" as *const u8 as *const libc::c_char as *mut libc::c_char, + b"utf-8\x00" as *const u8 as *const libc::c_char as *mut libc::c_char, + ) as *mut libc::c_void, + ); + mime_fields = mailmime_fields_new_encoding(MAILMIME_MECHANISM_8BIT as libc::c_int); + message_part = mailmime_new_empty(content, mime_fields); + } set_body_text(message_part, text); message_part } -unsafe fn set_body_text(part: *mut mailmime, text: &str) { - mailmime_set_body_text(part, text.strdup(), text.len()); +fn set_body_text(part: *mut mailmime, text: &str) { + unsafe { + mailmime_set_body_text(part, text.strdup(), text.len()); + } } #[allow(non_snake_case)] @@ -950,7 +887,7 @@ fn build_body_file(context: &Context, msg: &Message, base_name: &str) -> (*mut m } } let content = mailmime_content_new_with_str(mimetype.strdup()); - let filename_encoded = dc_encode_header_words(&filename_to_send); + let filename_encoded = dc_encode_header_words(&filename_to_send).strdup(); clist_insert_after( (*content).ct_parameters, (*(*content).ct_parameters).last, @@ -969,6 +906,16 @@ fn build_body_file(context: &Context, msg: &Message, base_name: &str) -> (*mut m } } +pub(crate) fn vec_contains_lowercase(vec: &Vec, part: &str) -> bool { + let partlc = part.to_lowercase(); + for cur in vec.iter() { + if (*cur).to_lowercase() == partlc { + return true; + } + } + false +} + /******************************************************************************* * Render ******************************************************************************/ diff --git a/src/dc_strencode.rs b/src/dc_strencode.rs index a4ec6c318..6a850c15e 100644 --- a/src/dc_strencode.rs +++ b/src/dc_strencode.rs @@ -25,7 +25,7 @@ use crate::dc_tools::*; * @return Returns the encoded string which must be free()'d when no longed needed. * On errors, NULL is returned. */ -pub unsafe fn dc_encode_header_words(to_encode_r: impl AsRef) -> *mut libc::c_char { +pub unsafe fn dc_encode_header_words(to_encode_r: impl AsRef) -> String { let to_encode = CString::new(to_encode_r.as_ref().as_bytes()).expect("invalid cstring to_encode"); @@ -116,7 +116,9 @@ pub unsafe fn dc_encode_header_words(to_encode_r: impl AsRef) -> *mut libc: } } - ret_str + let s = to_string(ret_str); + free(ret_str.cast()); + s } unsafe fn quote_word( @@ -330,7 +332,7 @@ unsafe fn print_hex(target: *mut libc::c_char, cur: *const libc::c_char) { mod tests { use super::*; - use libc::{strcmp, strncmp}; + use libc::strcmp; use std::ffi::CStr; #[test] @@ -353,19 +355,15 @@ mod tests { assert_eq!(CStr::from_ptr(buf1).to_str().unwrap(), "just ascii test"); free(buf1 as *mut libc::c_void); - buf1 = dc_encode_header_words("abcdef"); - assert_eq!(CStr::from_ptr(buf1).to_str().unwrap(), "abcdef"); - free(buf1 as *mut libc::c_void); + assert_eq!(dc_encode_header_words("abcdef"), "abcdef"); - buf1 = dc_encode_header_words( + let r = dc_encode_header_words( std::string::String::from_utf8(b"test\xc3\xa4\xc3\xb6\xc3\xbc.txt".to_vec()) .unwrap(), ); - assert_eq!( - strncmp(buf1, b"=?utf-8\x00" as *const u8 as *const libc::c_char, 7), - 0 - ); + assert!(r.starts_with("=?utf-8")); + buf1 = r.strdup(); let buf2: *mut libc::c_char = dc_decode_header_words(buf1); assert_eq!( strcmp( @@ -374,7 +372,6 @@ mod tests { ), 0 ); - free(buf1 as *mut libc::c_void); free(buf2 as *mut libc::c_void); buf1 = dc_decode_header_words( @@ -388,7 +385,6 @@ mod tests { ), 0 ); - free(buf1 as *mut libc::c_void); } } diff --git a/src/dc_tools.rs b/src/dc_tools.rs index 9ecfbb5e1..a7fdda9fb 100644 --- a/src/dc_tools.rs +++ b/src/dc_tools.rs @@ -9,7 +9,7 @@ use std::time::SystemTime; use std::{fmt, fs, ptr}; use chrono::{Local, TimeZone}; -use libc::{free, memcpy, strcpy, strlen, strstr, uintptr_t}; +use libc::{memcpy, strcpy, strlen, uintptr_t}; use mmime::clist::*; use mmime::mailimf_types::*; use rand::{thread_rng, Rng}; @@ -241,32 +241,14 @@ pub(crate) unsafe fn dc_str_from_clist( res.strdup() } -pub(crate) unsafe fn dc_str_to_clist( - str: *const libc::c_char, - delimiter: *const libc::c_char, -) -> *mut clist { - let list: *mut clist = clist_new(); - assert!(!list.is_null()); - - if !str.is_null() && !delimiter.is_null() && strlen(delimiter) >= 1 { - let mut p1: *const libc::c_char = str; - loop { - let p2: *const libc::c_char = strstr(p1, delimiter); - if p2.is_null() { - clist_insert_after(list, (*list).last, strdup(p1) as *mut libc::c_void); - break; - } else { - clist_insert_after( - list, - (*list).last, - strndup(p1, p2.wrapping_offset_from(p1) as libc::c_ulong) as *mut libc::c_void, - ); - p1 = p2.add(strlen(delimiter)) - } +pub(crate) fn dc_str_to_clist(str: &str, delimiter: &str) -> *mut clist { + unsafe { + let list: *mut clist = clist_new(); + for cur in str.split(&delimiter) { + clist_insert_after(list, (*list).last, cur.strdup().cast()); } + list } - - list } /* the colors must fulfill some criterions as: @@ -293,32 +275,6 @@ pub(crate) fn dc_str_to_color(s: impl AsRef) -> u32 { COLORS[color_index] } -/* clist tools */ - -/* calls free() for each item content */ -pub(crate) unsafe fn clist_free_content(haystack: *const clist) { - let mut iter = (*haystack).first; - - while !iter.is_null() { - free((*iter).data); - (*iter).data = ptr::null_mut(); - iter = if !iter.is_null() { - (*iter).next - } else { - ptr::null_mut() - } - } -} - -pub(crate) unsafe fn clist_search_string_nocase( - haystack: *const clist, - needle: *const libc::c_char, -) -> bool { - (&*haystack) - .into_iter() - .any(|data| strcasecmp(data.cast(), needle) == 0) -} - /* date/time tools */ /* the result is UTC or DC_INVALID_TIMESTAMP */ pub(crate) unsafe fn dc_timestamp_from_date(date_time: *mut mailimf_date_time) -> i64 { @@ -496,25 +452,15 @@ pub(crate) fn dc_extract_grpid_from_rfc724_mid(mid: &str) -> Option<&str> { None } -pub(crate) unsafe fn dc_extract_grpid_from_rfc724_mid_list( - list: *const clist, -) -> *mut libc::c_char { +pub(crate) fn dc_extract_grpid_from_rfc724_mid_list(list: *const clist) -> *mut libc::c_char { if !list.is_null() { - let mut cur: *mut clistiter = (*list).first; - while !cur.is_null() { - let mid = if !cur.is_null() { - as_str((*cur).data as *const libc::c_char) - } else { - "" - }; + unsafe { + for cur in (*list).into_iter() { + let mid = as_str(cur as *const libc::c_char); - if let Some(grpid) = dc_extract_grpid_from_rfc724_mid(mid) { - return grpid.strdup(); - } - cur = if !cur.is_null() { - (*cur).next - } else { - ptr::null_mut() + if let Some(grpid) = dc_extract_grpid_from_rfc724_mid(mid) { + return grpid.strdup(); + } } } } @@ -1082,21 +1028,6 @@ pub(crate) unsafe fn strdup(s: *const libc::c_char) -> *mut libc::c_char { result as *mut _ } -pub(crate) fn strndup(s: *const libc::c_char, n: libc::c_ulong) -> *mut libc::c_char { - if s.is_null() { - return std::ptr::null_mut(); - } - - let end = std::cmp::min(n as usize, unsafe { strlen(s) }); - unsafe { - let result = libc::malloc(end + 1); - memcpy(result, s as *const _, end); - std::ptr::write_bytes(result.offset(end as isize), b'\x00', 1); - - result as *mut _ - } -} - pub(crate) unsafe fn strcasecmp(s1: *const libc::c_char, s2: *const libc::c_char) -> libc::c_int { let s1 = std::ffi::CStr::from_ptr(s1) .to_string_lossy() @@ -1115,7 +1046,7 @@ pub(crate) unsafe fn strcasecmp(s1: *const libc::c_char, s2: *const libc::c_char mod tests { use super::*; - use libc::strcmp; + use libc::{free, strcmp}; use std::convert::TryInto; use std::ffi::CStr; @@ -1147,24 +1078,6 @@ mod tests { } } - #[test] - fn test_dc_strdup_keep_null() { - unsafe { - let str_a = b"foobar\x00" as *const u8 as *const libc::c_char; - let str_a_copy = dc_strdup_keep_null(str_a); - assert_eq!( - CStr::from_ptr(str_a_copy), - CString::new("foobar").unwrap().as_c_str() - ); - assert_ne!(str_a, str_a_copy); - - let str_a = ptr::null(); - let str_a_copy = dc_strdup_keep_null(str_a); - assert_eq!(str_a.is_null(), true); - assert_eq!(str_a_copy.is_null(), true); - } - } - #[test] fn test_dc_ltrim() { unsafe { @@ -1273,49 +1186,50 @@ mod tests { ); } + /* calls free() for each item content */ + unsafe fn clist_free_content(haystack: *const clist) { + let mut iter = (*haystack).first; + + while !iter.is_null() { + free((*iter).data); + (*iter).data = ptr::null_mut(); + iter = if !iter.is_null() { + (*iter).next + } else { + ptr::null_mut() + } + } + } + + fn strndup(s: *const libc::c_char, n: libc::c_ulong) -> *mut libc::c_char { + if s.is_null() { + return std::ptr::null_mut(); + } + + let end = std::cmp::min(n as usize, unsafe { strlen(s) }); + unsafe { + let result = libc::malloc(end + 1); + memcpy(result, s as *const _, end); + std::ptr::write_bytes(result.offset(end as isize), b'\x00', 1); + + result as *mut _ + } + } + #[test] fn test_dc_str_to_clist_1() { unsafe { - let list = dc_str_to_clist(ptr::null(), b" \x00" as *const u8 as *const libc::c_char); - assert_eq!((*list).count, 0); - clist_free_content(list); - clist_free(list); - } - } - - #[test] - fn test_dc_str_to_clist_2() { - unsafe { - let list: *mut clist = dc_str_to_clist( - b"\x00" as *const u8 as *const libc::c_char, - b" \x00" as *const u8 as *const libc::c_char, - ); + let list = dc_str_to_clist("", " "); assert_eq!((*list).count, 1); clist_free_content(list); clist_free(list); } } - #[test] - fn test_dc_str_to_clist_3() { - unsafe { - let list: *mut clist = dc_str_to_clist( - b" \x00" as *const u8 as *const libc::c_char, - b" \x00" as *const u8 as *const libc::c_char, - ); - assert_eq!((*list).count, 2); - clist_free_content(list); - clist_free(list); - } - } - #[test] fn test_dc_str_to_clist_4() { unsafe { - let list: *mut clist = dc_str_to_clist( - b"foo bar test\x00" as *const u8 as *const libc::c_char, - b" \x00" as *const u8 as *const libc::c_char, - ); + let list: *mut clist = dc_str_to_clist("foo bar test", " "); assert_eq!((*list).count, 3); let str: *mut libc::c_char = dc_str_from_clist(list, b" \x00" as *const u8 as *const libc::c_char); diff --git a/src/e2ee.rs b/src/e2ee.rs index 2301eddf8..6f12fc7d6 100644 --- a/src/e2ee.rs +++ b/src/e2ee.rs @@ -53,7 +53,7 @@ impl E2eeHelper { pub unsafe fn encrypt( &mut self, context: &Context, - recipients_addr: *const clist, + recipients_addr: &Vec, force_unencrypted: bool, e2ee_guaranteed: bool, min_verified: libc::c_int, @@ -69,10 +69,7 @@ impl E2eeHelper { let plain: *mut MMAPString = mmap_string_new(b"\x00" as *const u8 as *const libc::c_char); let mut peerstates: Vec = Vec::new(); - if !(recipients_addr.is_null() - || in_out_message.is_null() - || !(*in_out_message).mm_parent.is_null() - || plain.is_null()) + if !(in_out_message.is_null() || !(*in_out_message).mm_parent.is_null() || plain.is_null()) { /* libEtPan's pgp_encrypt_mime() takes the parent as the new root. We just expect the root as being given to this function. */ let prefer_encrypt = if 0 @@ -97,9 +94,8 @@ impl E2eeHelper { /*only for random-seed*/ if prefer_encrypt == EncryptPreference::Mutual || e2ee_guaranteed { do_encrypt = 1i32; - for cur_data in (*recipients_addr).into_iter() { - let recipient_addr = to_string(cur_data as *const libc::c_char); - if recipient_addr != addr { + for recipient_addr in recipients_addr.iter() { + if *recipient_addr != addr { let peerstate = Peerstate::from_addr(context, &context.sql, &recipient_addr); if peerstate.is_some() diff --git a/src/job.rs b/src/job.rs index 9492fc024..d98b6ac48 100644 --- a/src/job.rs +++ b/src/job.rs @@ -1,8 +1,6 @@ -use std::ptr; use std::time::Duration; use deltachat_derive::{FromSql, ToSql}; -use mmime::clist::*; use rand::{thread_rng, Rng}; use crate::chat; @@ -642,7 +640,7 @@ pub fn job_action_exists(context: &Context, action: Action) -> bool { /* special case for DC_JOB_SEND_MSG_TO_SMTP */ #[allow(non_snake_case)] -pub unsafe fn job_send_msg(context: &Context, msg_id: u32) -> libc::c_int { +pub fn job_send_msg(context: &Context, msg_id: u32) -> libc::c_int { let mut success = 0; /* load message data */ @@ -680,7 +678,7 @@ pub unsafe fn job_send_msg(context: &Context, msg_id: u32) -> libc::c_int { } } /* create message */ - if let Err(msg) = dc_mimefactory_render(context, &mut mimefactory) { + if let Err(msg) = unsafe { dc_mimefactory_render(context, &mut mimefactory) } { let e = msg.to_string(); message::set_msg_failed(context, msg_id, Some(e)); } else if 0 @@ -704,20 +702,12 @@ pub unsafe fn job_send_msg(context: &Context, msg_id: u32) -> libc::c_int { Some("End-to-end-encryption unavailable unexpectedly."), ); } else { - let from_addr_c = mimefactory.from_addr.strdup(); - if !clist_search_string_nocase(mimefactory.recipients_addr, from_addr_c) { - clist_insert_after( - mimefactory.recipients_names, - (*mimefactory.recipients_names).last, - ptr::null_mut(), - ); - clist_insert_after( - mimefactory.recipients_addr, - (*mimefactory.recipients_addr).last, - mimefactory.from_addr.strdup().cast(), - ); + if !vec_contains_lowercase(&mimefactory.recipients_addr, &mimefactory.from_addr) { + mimefactory.recipients_names.push("".to_string()); + mimefactory + .recipients_addr + .push(mimefactory.from_addr.to_string()); } - libc::free(from_addr_c.cast()); if mimefactory.out_gossiped { chat::set_gossiped_timestamp(context, mimefactory.msg.chat_id, time()); } @@ -1000,7 +990,7 @@ fn connect_to_inbox(context: &Context, inbox: &Imap) -> libc::c_int { } fn send_mdn(context: &Context, msg_id: u32) { - if let Ok(mut mimefactory) = unsafe { dc_mimefactory_load_mdn(context, msg_id) } { + if let Ok(mut mimefactory) = dc_mimefactory_load_mdn(context, msg_id) { if unsafe { dc_mimefactory_render(context, &mut mimefactory) }.is_ok() { add_smtp_job(context, Action::SendMdn, &mut mimefactory); } @@ -1010,7 +1000,6 @@ fn send_mdn(context: &Context, msg_id: u32) { #[allow(non_snake_case)] fn add_smtp_job(context: &Context, action: Action, mimefactory: &MimeFactory) -> libc::c_int { let mut success: libc::c_int = 0i32; - let mut recipients: *mut libc::c_char = ptr::null_mut(); let mut param = Params::new(); let path_filename = dc_get_fine_path_filename(context, "$BLOBDIR", &mimefactory.rfc724_mid); let bytes = unsafe { @@ -1027,14 +1016,9 @@ fn add_smtp_job(context: &Context, action: Action, mimefactory: &MimeFactory) -> path_filename.display(), ); } else { - recipients = unsafe { - dc_str_from_clist( - mimefactory.recipients_addr, - b"\x1e\x00" as *const u8 as *const libc::c_char, - ) - }; + let recipients = mimefactory.recipients_addr.join("\x1e"); param.set(Param::File, path_filename.to_string_lossy()); - param.set(Param::Recipients, as_str(recipients)); + param.set(Param::Recipients, &recipients); job_add( context, action, @@ -1048,9 +1032,6 @@ fn add_smtp_job(context: &Context, action: Action, mimefactory: &MimeFactory) -> ); success = 1; } - unsafe { - libc::free(recipients.cast()); - } success }