diff --git a/deltachat-ffi/src/lib.rs b/deltachat-ffi/src/lib.rs index 045053044..920a97a38 100644 --- a/deltachat-ffi/src/lib.rs +++ b/deltachat-ffi/src/lib.rs @@ -15,6 +15,7 @@ use num_traits::{FromPrimitive, ToPrimitive}; use std::ptr; use std::str::FromStr; +use deltachat::dc_tools::StrExt; use deltachat::*; // TODO: constants @@ -126,10 +127,7 @@ pub unsafe extern "C" fn dc_get_config( let context = &*context; match config::Config::from_str(dc_tools::as_str(key)) { - Ok(key) => { - let value = context.get_config(key).unwrap_or_default(); - dc_tools::to_cstring(value) - } + Ok(key) => context.get_config(key).unwrap_or_default().strdup(), Err(_) => std::ptr::null_mut(), } } @@ -154,7 +152,7 @@ pub unsafe extern "C" fn dc_get_oauth2_url( let addr = dc_tools::to_string(addr); let redirect = dc_tools::to_string(redirect); match oauth2::dc_get_oauth2_url(context, addr, redirect) { - Some(res) => dc_tools::to_cstring(res), + Some(res) => res.strdup(), None => std::ptr::null_mut(), } } diff --git a/examples/repl/cmdline.rs b/examples/repl/cmdline.rs index f6bcb083d..2ed21522a 100644 --- a/examples/repl/cmdline.rs +++ b/examples/repl/cmdline.rs @@ -147,7 +147,7 @@ unsafe fn poke_spec(context: &Context, spec: *const libc::c_char) -> libc::c_int } else { current_block = 7149356873433890176; } - real_spec = to_cstring(rs.unwrap_or_default()); + real_spec = rs.unwrap_or_default().strdup(); } match current_block { 8522321847195001863 => {} @@ -184,11 +184,10 @@ unsafe fn poke_spec(context: &Context, spec: *const libc::c_char) -> libc::c_int if name.ends_with(".eml") { let path_plus_name = format!("{}/{}", as_str(real_spec), name); info!(context, 0, "Import: {}", path_plus_name); - let path_plus_name_c = to_cstring(path_plus_name); - if 0 != dc_poke_eml_file(context, path_plus_name_c) { + let path_plus_name_c = CString::yolo(path_plus_name); + if 0 != dc_poke_eml_file(context, path_plus_name_c.as_ptr()) { read_cnt += 1 } - free(path_plus_name_c as *mut _); } } current_block = 1622411330066726685; @@ -386,13 +385,13 @@ pub unsafe fn dc_cmdline(context: &Context, line: &str) -> Result<(), failure::E let arg1_c = if arg1.is_empty() { std::ptr::null() } else { - to_cstring(arg1) as *const _ + arg1.strdup() as *const _ }; let arg2 = args.next().unwrap_or_default(); let arg2_c = if arg2.is_empty() { std::ptr::null() } else { - to_cstring(arg2) as *const _ + arg2.strdup() as *const _ }; match arg0 { @@ -928,13 +927,11 @@ pub unsafe fn dc_cmdline(context: &Context, line: &str) -> Result<(), failure::E ensure!(!sel_chat.is_null(), "No chat selected."); ensure!(!arg1.is_empty(), "No message text given."); - let msg = to_cstring(format!("{} {}", arg1, arg2)); + let msg = CString::yolo(format!("{} {}", arg1, arg2)); - if 0 != dc_send_text_msg(context, dc_chat_get_id(sel_chat), msg) { + if 0 != dc_send_text_msg(context, dc_chat_get_id(sel_chat), msg.as_ptr()) { println!("Message sent."); - free(msg as *mut _); } else { - free(msg as *mut _); bail!("Sending failed."); } } diff --git a/examples/repl/main.rs b/examples/repl/main.rs index da7b28cab..b023c801e 100644 --- a/examples/repl/main.rs +++ b/examples/repl/main.rs @@ -481,7 +481,7 @@ unsafe fn handle_cmd(line: &str, ctx: Arc>) -> Result Chatlist<'a> { let mut ret = dc_lot_new(); if index >= self.ids.len() { - (*ret).text2 = to_cstring("ErrBadChatlistIndex"); + (*ret).text2 = "ErrBadChatlistIndex".strdup(); return ret; } @@ -267,7 +267,7 @@ impl<'a> Chatlist<'a> { chat = dc_chat_new(self.context); let chat_to_delete = chat; if !dc_chat_load_from_db(chat, self.ids[index].0) { - (*ret).text2 = to_cstring("ErrCannotReadChat"); + (*ret).text2 = "ErrCannotReadChat".strdup(); dc_chat_unref(chat_to_delete); return ret; @@ -293,7 +293,7 @@ impl<'a> Chatlist<'a> { if (*chat).id == DC_CHAT_ID_ARCHIVED_LINK as u32 { (*ret).text2 = dc_strdup(0 as *const libc::c_char) } else if lastmsg.is_null() || (*lastmsg).from_id == DC_CONTACT_ID_SELF as u32 { - (*ret).text2 = to_cstring(self.context.stock_str(StockMessage::NoMessages)); + (*ret).text2 = self.context.stock_str(StockMessage::NoMessages).strdup(); } else { dc_lot_fill(ret, lastmsg, chat, lastcontact, self.context); } diff --git a/src/config.rs b/src/config.rs index ff7aa0905..f4be262b3 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,3 +1,5 @@ +use std::ffi::CString; + use strum::{EnumProperty, IntoEnumIterator}; use strum_macros::{AsRefStr, Display, EnumIter, EnumProperty, EnumString}; @@ -72,10 +74,8 @@ impl Context { let rel_path = self.sql.get_config(self, key); rel_path.map(|p| { let v = unsafe { - let n = to_cstring(p); - let res = dc_get_abs_path(self, n); - free(n as *mut libc::c_void); - res + let n = CString::yolo(p); + dc_get_abs_path(self, n.as_ptr()) }; let r = to_string(v); unsafe { free(v as *mut _) }; diff --git a/src/context.rs b/src/context.rs index 46613ffe9..ba12edc21 100644 --- a/src/context.rs +++ b/src/context.rs @@ -483,7 +483,7 @@ pub unsafe fn dc_get_info(context: &Context) -> *mut libc::c_char { fingerprint_str, ); - to_cstring(res) + res.strdup() } pub unsafe fn dc_get_version_str() -> *mut libc::c_char { diff --git a/src/dc_array.rs b/src/dc_array.rs index 5e0fb97fa..224ef9cc8 100644 --- a/src/dc_array.rs +++ b/src/dc_array.rs @@ -271,7 +271,7 @@ pub unsafe fn dc_array_get_marker(array: *const dc_array_t, index: size_t) -> *m if let dc_array_t::Locations(v) = &*array { if let Some(s) = &v[index].marker { - to_cstring(s) + s.strdup() } else { std::ptr::null_mut() } @@ -375,7 +375,7 @@ pub unsafe fn dc_array_get_string( res + sep + &n.to_string() } }); - to_cstring(res) + res.strdup() } else { panic!("Attempt to get string from array of other type"); } diff --git a/src/dc_chat.rs b/src/dc_chat.rs index 03ebd1c03..23b5956dd 100644 --- a/src/dc_chat.rs +++ b/src/dc_chat.rs @@ -137,14 +137,8 @@ pub fn dc_chat_load_from_db(chat: *mut Chat, chat_id: u32) -> bool { c.id = row.get(0)?; c.type_0 = row.get(1)?; - c.name = { - let raw: String = row.get(2)?; - unsafe { to_cstring(raw) } - }; - c.grpid = { - let raw: String = row.get(3)?; - unsafe { to_cstring(raw) } - }; + c.name = unsafe { row.get::<_, String>(2)?.strdup() }; + c.grpid = unsafe { row.get::<_, String>(3)?.strdup() }; c.param = row.get::<_, String>(4)?.parse().unwrap_or_default(); c.archived = row.get(5)?; @@ -172,24 +166,27 @@ pub fn dc_chat_load_from_db(chat: *mut Chat, chat_id: u32) -> bool { match c.id { 1 => unsafe { free((*chat).name as *mut libc::c_void); - (*chat).name = to_cstring((*chat).context.stock_str(StockMessage::DeadDrop)); + (*chat).name = (*chat).context.stock_str(StockMessage::DeadDrop).strdup(); }, 6 => unsafe { free((*chat).name as *mut libc::c_void); let tempname = (*chat).context.stock_str(StockMessage::ArchivedChats); let cnt = dc_get_archived_cnt((*chat).context); - (*chat).name = to_cstring(format!("{} ({})", tempname, cnt)); + (*chat).name = format!("{} ({})", tempname, cnt).strdup(); }, 5 => unsafe { free((*chat).name as *mut libc::c_void); - (*chat).name = to_cstring((*chat).context.stock_str(StockMessage::StarredMsgs)); + (*chat).name = (*chat) + .context + .stock_str(StockMessage::StarredMsgs) + .strdup(); }, _ => { if unsafe { &(*chat).param }.exists(Param::Selftalk) { unsafe { free((*chat).name as *mut libc::c_void); (*chat).name = - to_cstring((*chat).context.stock_str(StockMessage::SelfMsg)); + (*chat).context.stock_str(StockMessage::SelfMsg).strdup(); } } } @@ -398,7 +395,7 @@ unsafe fn prepare_msg_common<'a>( let mut pathNfilename = (*msg) .param .get(Param::File) - .map(|s| to_cstring(s)) + .map(|s| s.strdup()) .unwrap_or_else(|| std::ptr::null_mut()); if pathNfilename.is_null() { error!( @@ -516,16 +513,15 @@ unsafe fn prepare_msg_raw( if from.is_none() { error!(context, 0, "Cannot send message, not configured.",); } else { - let from_c = to_cstring(from.unwrap()); + let from_c = CString::yolo(from.unwrap()); new_rfc724_mid = dc_create_outgoing_rfc724_mid( if (*chat).type_0 == 120 || (*chat).type_0 == 130 { (*chat).grpid } else { 0 as *mut libc::c_char }, - from_c, + from_c.as_ptr(), ); - free(from_c as *mut _); if (*chat).type_0 == DC_CHAT_TYPE_SINGLE { if let Some(id) = context.sql.query_row_col( @@ -789,9 +785,9 @@ unsafe fn get_parent_mime_headers( FROM msgs WHERE chat_id=? AND from_id!=?);", params![(*chat).id as i32, 1], |row| { - *parent_rfc724_mid = to_cstring(row.get::<_, String>(0)?); - *parent_in_reply_to = to_cstring(row.get::<_, String>(1)?); - *parent_references = to_cstring(row.get::<_, String>(2)?); + *parent_rfc724_mid = row.get::<_, String>(0)?.strdup(); + *parent_in_reply_to = row.get::<_, String>(1)?.strdup(); + *parent_references = row.get::<_, String>(2)?.strdup(); Ok(()) }, ) @@ -807,9 +803,9 @@ unsafe fn get_parent_mime_headers( FROM msgs WHERE chat_id=? AND from_id==?);", params![(*chat).id as i32, 1], |row| { - *parent_rfc724_mid = to_cstring(row.get::<_, String>(0)?); - *parent_in_reply_to = to_cstring(row.get::<_, String>(1)?); - *parent_references = to_cstring(row.get::<_, String>(2)?); + *parent_rfc724_mid = row.get::<_, String>(0)?.strdup(); + *parent_in_reply_to = row.get::<_, String>(1)?.strdup(); + *parent_references = row.get::<_, String>(2)?.strdup(); Ok(()) }, ) @@ -1012,7 +1008,7 @@ unsafe fn set_draft_raw(context: &Context, chat_id: uint32_t, msg: *mut dc_msg_t let mut pathNfilename = (*msg) .param .get(Param::File) - .map(|s| to_cstring(s)) + .map(|s| s.strdup()) .unwrap_or_else(|| std::ptr::null_mut()); if pathNfilename.is_null() { OK_TO_CONTINUE = false; @@ -1620,12 +1616,14 @@ pub unsafe fn dc_add_contact_to_chat_ex( if OK_TO_CONTINUE { if (*chat).param.get_int(Param::Unpromoted).unwrap_or_default() == 0 { (*msg).type_0 = Viewtype::Text; - (*msg).text = to_cstring(context.stock_system_msg( - StockMessage::MsgAddMember, - as_str((*contact).addr), - "", - DC_CONTACT_ID_SELF as uint32_t, - )); + (*msg).text = context + .stock_system_msg( + StockMessage::MsgAddMember, + as_str((*contact).addr), + "", + DC_CONTACT_ID_SELF as uint32_t, + ) + .strdup(); (*msg).param.set_int(Param::Cmd, 4); if !(*contact).addr.is_null() { (*msg).param.set(Param::Arg, as_str((*contact).addr)); @@ -1733,19 +1731,23 @@ pub unsafe fn dc_remove_contact_from_chat( (*msg).type_0 = Viewtype::Text; if (*contact).id == 1 as libc::c_uint { dc_set_group_explicitly_left(context, (*chat).grpid); - (*msg).text = to_cstring(context.stock_system_msg( - StockMessage::MsgGroupLeft, - "", - "", - DC_CONTACT_ID_SELF as u32, - )); + (*msg).text = context + .stock_system_msg( + StockMessage::MsgGroupLeft, + "", + "", + DC_CONTACT_ID_SELF as u32, + ) + .strdup(); } else { - (*msg).text = to_cstring(context.stock_system_msg( - StockMessage::MsgDelMember, - as_str((*contact).addr), - "", - DC_CONTACT_ID_SELF as u32, - )); + (*msg).text = context + .stock_system_msg( + StockMessage::MsgDelMember, + as_str((*contact).addr), + "", + DC_CONTACT_ID_SELF as u32, + ) + .strdup(); } (*msg).param.set_int(Param::Cmd, 5); if !(*contact).addr.is_null() { @@ -1846,12 +1848,14 @@ pub unsafe fn dc_set_chat_name( { if (*chat).param.get_int(Param::Unpromoted).unwrap_or_default() == 0 { (*msg).type_0 = Viewtype::Text; - (*msg).text = to_cstring(context.stock_system_msg( - StockMessage::MsgGrpName, - as_str((*chat).name), - as_str(new_name), - DC_CONTACT_ID_SELF as u32, - )); + (*msg).text = context + .stock_system_msg( + StockMessage::MsgGrpName, + as_str((*chat).name), + as_str(new_name), + DC_CONTACT_ID_SELF as u32, + ) + .strdup(); (*msg).param.set_int(Param::Cmd, 2); if !(*chat).name.is_null() { (*msg).param.set(Param::Arg, as_str((*chat).name)); @@ -1918,16 +1922,18 @@ pub unsafe fn dc_set_chat_profile_image( (*msg).param.set_int(Param::Cmd, 3); (*msg).param.set(Param::Arg, as_str(new_image_rel)); (*msg).type_0 = Viewtype::Text; - (*msg).text = to_cstring(context.stock_system_msg( - if !new_image_rel.is_null() { - StockMessage::MsgGrpImgChanged - } else { - StockMessage::MsgGrpImgDeleted - }, - "", - "", - DC_CONTACT_ID_SELF as uint32_t, - )); + (*msg).text = context + .stock_system_msg( + if !new_image_rel.is_null() { + StockMessage::MsgGrpImgChanged + } else { + StockMessage::MsgGrpImgDeleted + }, + "", + "", + DC_CONTACT_ID_SELF as uint32_t, + ) + .strdup(); (*msg).id = dc_send_msg(context, chat_id, msg); context.call_cb( Event::MSGS_CHANGED, @@ -2094,7 +2100,10 @@ pub unsafe fn dc_chat_get_subtitle(chat: *const Chat) -> *mut libc::c_char { let mut ret: *mut libc::c_char = std::ptr::null_mut(); if (*chat).type_0 == 100 && (*chat).param.exists(Param::Selftalk) { - ret = to_cstring((*chat).context.stock_str(StockMessage::SelfTalkSubTitle)); + ret = (*chat) + .context + .stock_str(StockMessage::SelfTalkSubTitle) + .strdup(); } else if (*chat).type_0 == 100 { let ret_raw: String = (*chat) .context @@ -2108,17 +2117,16 @@ pub unsafe fn dc_chat_get_subtitle(chat: *const Chat) -> *mut libc::c_char { 0, ) .unwrap_or_else(|| "Err".into()); - ret = to_cstring(ret_raw); + ret = ret_raw.strdup(); } else if (*chat).type_0 == 120 || (*chat).type_0 == 130 { if (*chat).id == 1 { - ret = to_cstring((*chat).context.stock_str(StockMessage::DeadDrop)); + ret = (*chat).context.stock_str(StockMessage::DeadDrop).strdup(); } else { let cnt = dc_get_chat_contact_cnt((*chat).context, (*chat).id); - ret = to_cstring( - (*chat) - .context - .stock_string_repl_int(StockMessage::Member, cnt), - ); + ret = (*chat) + .context + .stock_string_repl_int(StockMessage::Member, cnt) + .strdup(); } } return if !ret.is_null() { @@ -2146,7 +2154,11 @@ pub unsafe fn dc_chat_get_profile_image(chat: *const Chat) -> *mut libc::c_char let mut contacts: *mut dc_array_t = 0 as *mut dc_array_t; let mut contact: *mut dc_contact_t = 0 as *mut dc_contact_t; if !(chat.is_null() || (*chat).magic != 0xc4a7c4a7u32) { - image_rel = to_cstring((*chat).param.get(Param::ProfileImage).unwrap_or_default()); + image_rel = (*chat) + .param + .get(Param::ProfileImage) + .unwrap_or_default() + .strdup(); if !image_rel.is_null() && 0 != *image_rel.offset(0isize) as libc::c_int { image_abs = dc_get_abs_path((*chat).context, image_rel) } else if (*chat).type_0 == 100i32 { diff --git a/src/dc_configure.rs b/src/dc_configure.rs index a1397742a..73f449e7b 100644 --- a/src/dc_configure.rs +++ b/src/dc_configure.rs @@ -1102,14 +1102,14 @@ unsafe fn moz_autoconfigure( tag_config: 0, }; - let url_c = to_cstring(url); + let url_c = url.strdup(); let xml_raw = read_autoconf_file(context, url_c); free(url_c as *mut libc::c_void); if xml_raw.is_null() { return None; } - moz_ac.in_emaillocalpart = to_cstring(¶m_in.addr); + moz_ac.in_emaillocalpart = param_in.addr.strdup(); let p = strchr(moz_ac.in_emaillocalpart, '@' as i32); if p.is_null() { @@ -1166,7 +1166,7 @@ unsafe fn moz_autoconfigure_text_cb( let mut moz_ac: *mut moz_autoconfigure_t = userdata as *mut moz_autoconfigure_t; let mut val: *mut libc::c_char = dc_strdup(text); dc_trim(val); - let addr = to_cstring(&(*moz_ac).in_0.addr); + let addr = (*moz_ac).in_0.addr.strdup(); dc_str_replace( &mut val, b"%EMAILADDRESS%\x00" as *const u8 as *const libc::c_char, @@ -1306,7 +1306,7 @@ fn read_autoconf_file(context: &Context, url: *const libc::c_char) -> *mut libc: .send() .and_then(|mut res| res.text()) { - Ok(res) => unsafe { to_cstring(res) }, + Ok(res) => unsafe { res.strdup() }, Err(_err) => { info!(context, 0, "Can\'t read file.",); @@ -1322,7 +1322,7 @@ unsafe fn outlk_autodiscover( ) -> Option { let current_block: u64; let mut xml_raw: *mut libc::c_char = 0 as *mut libc::c_char; - let mut url = to_cstring(url__); + let mut url = url__.strdup(); let mut outlk_ad = outlk_autodiscover_t { in_0: param_in, out: dc_loginparam_new(), diff --git a/src/dc_contact.rs b/src/dc_contact.rs index 1beeb3a81..3b5b5b0d4 100644 --- a/src/dc_contact.rs +++ b/src/dc_contact.rs @@ -278,14 +278,13 @@ pub unsafe fn dc_contact_load_from_db( if contact_id == 1 as libc::c_uint { (*contact).id = contact_id; - (*contact).name = to_cstring((*contact).context.stock_str(StockMessage::SelfMsg)); - (*contact).addr = to_cstring( - (*contact) - .context - .sql - .get_config((*contact).context, "configured_addr") - .unwrap_or_default(), - ); + (*contact).name = (*contact).context.stock_str(StockMessage::SelfMsg).strdup(); + (*contact).addr = (*contact) + .context + .sql + .get_config((*contact).context, "configured_addr") + .unwrap_or_default() + .strdup(); true } else { sql.query_row( @@ -293,11 +292,11 @@ pub unsafe fn dc_contact_load_from_db( params![contact_id as i32], |row| { (*contact).id = contact_id; - (*contact).name = to_cstring(row.get::<_, String>(0)?); - (*contact).addr = to_cstring(row.get::<_, String>(1)?); + (*contact).name = row.get::<_, String>(0)?.strdup(); + (*contact).addr = row.get::<_, String>(1)?.strdup(); (*contact).origin = row.get(2)?; (*contact).blocked = row.get::<_, Option>(3)?.unwrap_or_default(); - (*contact).authname = to_cstring(row.get::<_, String>(4)?); + (*contact).authname = row.get::<_, String>(4)?.strdup(); Ok(()) } ).is_ok() @@ -726,7 +725,7 @@ pub unsafe fn dc_get_contact_encrinfo( free(fingerprint_other_verified as *mut libc::c_void); free(fingerprint_other_unverified as *mut libc::c_void); - to_cstring(ret) + ret.strdup() } unsafe fn cat_fingerprint( @@ -901,7 +900,7 @@ pub fn dc_contact_get_profile_image(contact: *const dc_contact_t) -> *mut libc:: if unsafe { (*contact).id } == 1 { let context = unsafe { (*contact) }.context; if let Some(avatar) = context.get_config(config::Config::Selfavatar) { - image_abs = unsafe { to_cstring(avatar) }; + image_abs = unsafe { avatar.strdup() }; } } // TODO: else get image_abs from contact param diff --git a/src/dc_dehtml.rs b/src/dc_dehtml.rs index ae0cd7546..bc9747556 100644 --- a/src/dc_dehtml.rs +++ b/src/dc_dehtml.rs @@ -53,7 +53,7 @@ pub unsafe fn dc_dehtml(buf_terminated: *mut libc::c_char) -> *mut libc::c_char dc_saxparser_parse(&mut saxparser, buf_terminated); free(dehtml.last_href as *mut libc::c_void); - to_cstring(dehtml.strbuilder) + dehtml.strbuilder.strdup() } unsafe fn dehtml_text_cb( diff --git a/src/dc_e2ee.rs b/src/dc_e2ee.rs index 3232a9a91..70e77544a 100644 --- a/src/dc_e2ee.rs +++ b/src/dc_e2ee.rs @@ -177,16 +177,12 @@ pub unsafe fn dc_e2ee_encrypt( let p = peerstates[i as usize] .render_gossip_header(min_verified as usize); - if p.is_some() { - let header = to_cstring(p.unwrap()); + if let Some(header) = p { mailimf_fields_add( imffields_encrypted, mailimf_field_new_custom( - strdup( - b"Autocrypt-Gossip\x00" as *const u8 - as *const libc::c_char, - ), - header, + "Autocrypt-Gossip".strdup(), + header.strdup(), ), ); } @@ -296,7 +292,7 @@ pub unsafe fn dc_e2ee_encrypt( sign_key.as_ref(), ) { let ctext_bytes = ctext_v.len(); - let ctext = to_cstring(ctext_v); + let ctext = ctext_v.strdup(); (*helper).cdata_to_free = ctext as *mut _; /* create MIME-structure that will contain the encrypted text */ @@ -354,13 +350,11 @@ pub unsafe fn dc_e2ee_encrypt( 14181132614457621749 => {} _ => { let aheader = Aheader::new(addr, public_key, prefer_encrypt); - let rendered = to_cstring(aheader.to_string()); - mailimf_fields_add( imffields_unprotected, mailimf_field_new_custom( - strdup(b"Autocrypt\x00" as *const u8 as *const libc::c_char), - rendered, + "Autocrypt".strdup(), + aheader.to_string().strdup(), ), ); } diff --git a/src/dc_imex.rs b/src/dc_imex.rs index cc6ffaf33..0ca50eb4b 100644 --- a/src/dc_imex.rs +++ b/src/dc_imex.rs @@ -515,7 +515,7 @@ pub unsafe fn dc_normalize_setup_code( p1 = p1.offset(1); } - to_cstring(out) + out.strdup() } #[allow(non_snake_case)] @@ -524,16 +524,14 @@ pub unsafe fn dc_job_do_DC_JOB_IMEX_IMAP(context: &Context, job: *mut dc_job_t) let mut success: libc::c_int = 0; let mut ongoing_allocated_here: libc::c_int = 0; let what: libc::c_int; - let mut param1 = 0 as *mut libc::c_char; - let mut param2 = 0 as *mut libc::c_char; if !(0 == dc_alloc_ongoing(context)) { ongoing_allocated_here = 1; what = (*job).param.get_int(Param::Cmd).unwrap_or_default(); - param1 = to_cstring((*job).param.get(Param::Arg).unwrap_or_default()); - param2 = to_cstring((*job).param.get(Param::Arg2).unwrap_or_default()); + let param1 = CString::yolo((*job).param.get(Param::Arg).unwrap_or_default()); + let _param2 = CString::yolo((*job).param.get(Param::Arg2).unwrap_or_default()); - if strlen(param1) == 0 { + if strlen(param1.as_ptr()) == 0 { error!(context, 0, "No Import/export dir/file given.",); } else { info!(context, 0, "Import/export process started.",); @@ -551,7 +549,7 @@ pub unsafe fn dc_job_do_DC_JOB_IMEX_IMAP(context: &Context, job: *mut dc_job_t) ); current_block = 3568988166330621280; } else { - dc_create_folder(context, param1); + dc_create_folder(context, param1.as_ptr()); current_block = 4495394744059808450; } } else { @@ -564,28 +562,28 @@ pub unsafe fn dc_job_do_DC_JOB_IMEX_IMAP(context: &Context, job: *mut dc_job_t) current_block = 10991094515395304355; match current_block { 2973387206439775448 => { - if 0 == import_backup(context, param1) { + if 0 == import_backup(context, param1.as_ptr()) { current_block = 3568988166330621280; } else { current_block = 1118134448028020070; } } 11250025114629486028 => { - if 0 == import_self_keys(context, param1) { + if 0 == import_self_keys(context, param1.as_ptr()) { current_block = 3568988166330621280; } else { current_block = 1118134448028020070; } } 12669919903773909120 => { - if 0 == export_backup(context, param1) { + if 0 == export_backup(context, param1.as_ptr()) { current_block = 3568988166330621280; } else { current_block = 1118134448028020070; } } _ => { - if 0 == export_self_keys(context, param1) { + if 0 == export_self_keys(context, param1.as_ptr()) { current_block = 3568988166330621280; } else { current_block = 1118134448028020070; @@ -604,28 +602,28 @@ pub unsafe fn dc_job_do_DC_JOB_IMEX_IMAP(context: &Context, job: *mut dc_job_t) current_block = 11250025114629486028; match current_block { 2973387206439775448 => { - if 0 == import_backup(context, param1) { + if 0 == import_backup(context, param1.as_ptr()) { current_block = 3568988166330621280; } else { current_block = 1118134448028020070; } } 11250025114629486028 => { - if 0 == import_self_keys(context, param1) { + if 0 == import_self_keys(context, param1.as_ptr()) { current_block = 3568988166330621280; } else { current_block = 1118134448028020070; } } 12669919903773909120 => { - if 0 == export_backup(context, param1) { + if 0 == export_backup(context, param1.as_ptr()) { current_block = 3568988166330621280; } else { current_block = 1118134448028020070; } } _ => { - if 0 == export_self_keys(context, param1) { + if 0 == export_self_keys(context, param1.as_ptr()) { current_block = 3568988166330621280; } else { current_block = 1118134448028020070; @@ -644,28 +642,28 @@ pub unsafe fn dc_job_do_DC_JOB_IMEX_IMAP(context: &Context, job: *mut dc_job_t) current_block = 12669919903773909120; match current_block { 2973387206439775448 => { - if 0 == import_backup(context, param1) { + if 0 == import_backup(context, param1.as_ptr()) { current_block = 3568988166330621280; } else { current_block = 1118134448028020070; } } 11250025114629486028 => { - if 0 == import_self_keys(context, param1) { + if 0 == import_self_keys(context, param1.as_ptr()) { current_block = 3568988166330621280; } else { current_block = 1118134448028020070; } } 12669919903773909120 => { - if 0 == export_backup(context, param1) { + if 0 == export_backup(context, param1.as_ptr()) { current_block = 3568988166330621280; } else { current_block = 1118134448028020070; } } _ => { - if 0 == export_self_keys(context, param1) { + if 0 == export_self_keys(context, param1.as_ptr()) { current_block = 3568988166330621280; } else { current_block = 1118134448028020070; @@ -684,28 +682,28 @@ pub unsafe fn dc_job_do_DC_JOB_IMEX_IMAP(context: &Context, job: *mut dc_job_t) current_block = 2973387206439775448; match current_block { 2973387206439775448 => { - if 0 == import_backup(context, param1) { + if 0 == import_backup(context, param1.as_ptr()) { current_block = 3568988166330621280; } else { current_block = 1118134448028020070; } } 11250025114629486028 => { - if 0 == import_self_keys(context, param1) { + if 0 == import_self_keys(context, param1.as_ptr()) { current_block = 3568988166330621280; } else { current_block = 1118134448028020070; } } 12669919903773909120 => { - if 0 == export_backup(context, param1) { + if 0 == export_backup(context, param1.as_ptr()) { current_block = 3568988166330621280; } else { current_block = 1118134448028020070; } } _ => { - if 0 == export_self_keys(context, param1) { + if 0 == export_self_keys(context, param1.as_ptr()) { current_block = 3568988166330621280; } else { current_block = 1118134448028020070; @@ -727,8 +725,6 @@ pub unsafe fn dc_job_do_DC_JOB_IMEX_IMAP(context: &Context, job: *mut dc_job_t) } } - free(param1 as *mut libc::c_void); - free(param2 as *mut libc::c_void); if 0 != ongoing_allocated_here { dc_free_ongoing(context); } @@ -875,9 +871,8 @@ unsafe fn export_backup(context: &Context, dir: *const libc::c_char) -> libc::c_ let res = chrono::NaiveDateTime::from_timestamp(now as i64, 0) .format("delta-chat-%Y-%m-%d.bak") .to_string(); - let buffer = to_cstring(res); - let dest_pathNfilename = dc_get_fine_pathNfilename(context, dir, buffer); - free(buffer as *mut _); + let buffer = CString::yolo(res); + let dest_pathNfilename = dc_get_fine_pathNfilename(context, dir, buffer.as_ptr()); if dest_pathNfilename.is_null() { error!(context, 0, "Cannot get backup file name.",); @@ -1076,7 +1071,6 @@ unsafe fn import_self_keys(context: &Context, dir_name: *const libc::c_char) -> let mut imported_cnt: libc::c_int = 0; let mut suffix: *mut libc::c_char = 0 as *mut libc::c_char; let mut path_plus_name: *mut libc::c_char = 0 as *mut libc::c_char; - let mut name_c: *mut libc::c_char = 0 as *mut libc::c_char; let mut set_default: libc::c_int; let mut buf: *mut libc::c_char = 0 as *mut libc::c_char; let mut buf_bytes: size_t = 0 as size_t; @@ -1104,9 +1098,8 @@ unsafe fn import_self_keys(context: &Context, dir_name: *const libc::c_char) -> let entry = entry.unwrap(); free(suffix as *mut libc::c_void); let name_f = entry.file_name(); - free(name_c as *mut libc::c_void); - name_c = to_cstring(name_f.to_string_lossy()); - suffix = dc_get_filesuffix_lc(name_c); + let name_c = name_f.to_c_string().unwrap(); + suffix = dc_get_filesuffix_lc(name_c.as_ptr()); if suffix.is_null() || strcmp(suffix, b"asc\x00" as *const u8 as *const libc::c_char) != 0 { @@ -1116,7 +1109,7 @@ unsafe fn import_self_keys(context: &Context, dir_name: *const libc::c_char) -> path_plus_name = dc_mprintf( b"%s/%s\x00" as *const u8 as *const libc::c_char, dir_name, - name_c, + name_c.as_ptr(), ); info!(context, 0, "Checking: {}", as_str(path_plus_name)); free(buf as *mut libc::c_void); @@ -1154,7 +1147,12 @@ unsafe fn import_self_keys(context: &Context, dir_name: *const libc::c_char) -> } } set_default = 1; - if !strstr(name_c, b"legacy\x00" as *const u8 as *const libc::c_char).is_null() { + if !strstr( + name_c.as_ptr(), + b"legacy\x00" as *const u8 as *const libc::c_char, + ) + .is_null() + { info!( context, 0, @@ -1179,7 +1177,6 @@ unsafe fn import_self_keys(context: &Context, dir_name: *const libc::c_char) -> } } - free(name_c as *mut libc::c_void); free(suffix as *mut libc::c_void); free(path_plus_name as *mut libc::c_void); free(buf as *mut libc::c_void); diff --git a/src/dc_job.rs b/src/dc_job.rs index 9bfa71dde..5efa05f53 100644 --- a/src/dc_job.rs +++ b/src/dc_job.rs @@ -314,7 +314,7 @@ unsafe fn dc_job_do_DC_JOB_SEND(context: &Context, job: &mut dc_job_t) { } match current_block { 13109137661213826276 => { - filename = to_cstring(job.param.get(Param::File).unwrap_or_default()); + filename = job.param.get(Param::File).unwrap_or_default().strdup(); if strlen(filename) == 0 { warn!(context, 0, "Missing file name for job {}", job.job_id,); } else if !(0 == dc_read_file(context, filename, &mut buf, &mut buf_bytes)) { @@ -1177,12 +1177,11 @@ pub unsafe fn dc_job_send_msg(context: &Context, msg_id: uint32_t) -> libc::c_in } else { // no redo, no IMAP. moreover, as the data does not exist, there is no need in calling dc_set_msg_failed() if msgtype_has_file((*mimefactory.msg).type_0) { - let pathNfilename = to_cstring( - (*mimefactory.msg) - .param - .get(Param::File) - .unwrap_or_default(), - ); + let pathNfilename = (*mimefactory.msg) + .param + .get(Param::File) + .unwrap_or_default() + .strdup(); if strlen(pathNfilename) > 0 { if ((*mimefactory.msg).type_0 == Viewtype::Image || (*mimefactory.msg).type_0 == Viewtype::Gif) diff --git a/src/dc_location.rs b/src/dc_location.rs index 14edc3767..c9e3ee66e 100644 --- a/src/dc_location.rs +++ b/src/dc_location.rs @@ -100,12 +100,9 @@ pub unsafe fn dc_send_locations_to_chat( { if 0 != seconds && !is_sending_locations_before { msg = dc_msg_new(context, Viewtype::Text); - (*msg).text = to_cstring(context.stock_system_msg( - StockMessage::MsgLocationEnabled, - "", - "", - 0, - )); + (*msg).text = context + .stock_system_msg(StockMessage::MsgLocationEnabled, "", "", 0) + .strdup(); (*msg).param.set_int(Param::Cmd, 8); dc_send_msg(context, chat_id, msg); } else if 0 == seconds && is_sending_locations_before { @@ -351,7 +348,7 @@ pub fn dc_get_location_kml( } if 0 != success { - unsafe { to_cstring(ret) } + unsafe { ret.strdup() } } else { std::ptr::null_mut() } @@ -365,7 +362,7 @@ unsafe fn get_kml_timestamp(utc: i64) -> *mut libc::c_char { let res = chrono::NaiveDateTime::from_timestamp(utc, 0) .format("%Y-%m-%dT%H:%M:%SZ") .to_string(); - to_cstring(res) + res.strdup() } pub unsafe fn dc_get_message_kml( diff --git a/src/dc_lot.rs b/src/dc_lot.rs index 429859636..3d4c714de 100644 --- a/src/dc_lot.rs +++ b/src/dc_lot.rs @@ -134,14 +134,14 @@ pub unsafe fn dc_lot_fill( return; } if (*msg).state == 19i32 { - (*lot).text1 = to_cstring(context.stock_str(StockMessage::Draft)); + (*lot).text1 = context.stock_str(StockMessage::Draft).strdup(); (*lot).text1_meaning = 1i32 } else if (*msg).from_id == 1i32 as libc::c_uint { if 0 != dc_msg_is_info(msg) || 0 != dc_chat_is_self_talk(chat) { (*lot).text1 = 0 as *mut libc::c_char; (*lot).text1_meaning = 0i32 } else { - (*lot).text1 = to_cstring(context.stock_str(StockMessage::SelfMsg)); + (*lot).text1 = context.stock_str(StockMessage::SelfMsg).strdup(); (*lot).text1_meaning = 3i32 } } else if chat.is_null() { diff --git a/src/dc_mimefactory.rs b/src/dc_mimefactory.rs index 22214b125..0cb95d780 100644 --- a/src/dc_mimefactory.rs +++ b/src/dc_mimefactory.rs @@ -158,13 +158,13 @@ pub unsafe fn dc_mimefactory_load_msg( |rows| { for row in rows { let (authname, addr) = row?; - let addr_c = to_cstring(addr); + let addr_c = addr.strdup(); if clist_search_string_nocase((*factory).recipients_addr, addr_c) == 0 { clist_insert_after( (*factory).recipients_names, (*(*factory).recipients_names).last, if !authname.is_empty() { - to_cstring(authname) + authname.strdup() } else { std::ptr::null_mut() } as *mut libc::c_void, @@ -188,7 +188,7 @@ pub unsafe fn dc_mimefactory_load_msg( if command == 5 { let email_to_remove = (*(*factory).msg).param.get(Param::Arg).unwrap_or_default(); - let email_to_remove_c = to_cstring(email_to_remove); + let email_to_remove_c = email_to_remove.strdup(); let self_addr = context .sql @@ -234,8 +234,8 @@ pub unsafe fn dc_mimefactory_load_msg( ); match row { Ok((in_reply_to, references)) => { - (*factory).in_reply_to = to_cstring(in_reply_to); - (*factory).references = to_cstring(references); + (*factory).in_reply_to = in_reply_to.strdup(); + (*factory).references = references.strdup(); } Err(err) => { error!( @@ -259,27 +259,28 @@ pub unsafe fn dc_mimefactory_load_msg( unsafe fn load_from(mut factory: *mut dc_mimefactory_t) { let context = (*factory).context; - (*factory).from_addr = to_cstring( - context - .sql - .get_config(context, "configured_addr") - .unwrap_or_default(), - ); + (*factory).from_addr = context + .sql + .get_config(context, "configured_addr") + .unwrap_or_default() + .strdup(); - (*factory).from_displayname = to_cstring( - context - .sql - .get_config(context, "displayname") - .unwrap_or_default(), - ); - (*factory).selfstatus = to_cstring( - context - .sql - .get_config(context, "selfstatus") - .unwrap_or_default(), - ); + (*factory).from_displayname = context + .sql + .get_config(context, "displayname") + .unwrap_or_default() + .strdup(); + + (*factory).selfstatus = context + .sql + .get_config(context, "selfstatus") + .unwrap_or_default() + .strdup(); if (*factory).selfstatus.is_null() { - (*factory).selfstatus = to_cstring((*factory).context.stock_str(StockMessage::StatusLine)); + (*factory).selfstatus = (*factory) + .context + .stock_str(StockMessage::StatusLine) + .strdup(); }; } @@ -573,8 +574,7 @@ pub unsafe fn dc_mimefactory_render(mut factory: *mut dc_mimefactory_t) -> libc: ), ); if command == 5 { - let email_to_remove = - to_cstring((*msg).param.get(Param::Arg).unwrap_or_default()); + let email_to_remove = (*msg).param.get(Param::Arg).unwrap_or_default().strdup(); if strlen(email_to_remove) > 0 { mailimf_fields_add( imf_fields, @@ -589,7 +589,7 @@ pub unsafe fn dc_mimefactory_render(mut factory: *mut dc_mimefactory_t) -> libc: } } else if command == 4 { do_gossip = 1; - let email_to_add = to_cstring((*msg).param.get(Param::Arg).unwrap_or_default()); + let email_to_add = (*msg).param.get(Param::Arg).unwrap_or_default().strdup(); if strlen(email_to_add) > 0 { mailimf_fields_add( imf_fields, @@ -619,7 +619,7 @@ pub unsafe fn dc_mimefactory_render(mut factory: *mut dc_mimefactory_t) -> libc: ); } } else if command == 2 { - let value_to_add = to_cstring((*msg).param.get(Param::Arg).unwrap_or_default()); + let value_to_add = (*msg).param.get(Param::Arg).unwrap_or_default().strdup(); mailimf_fields_add( imf_fields, mailimf_field_new_custom( @@ -661,11 +661,13 @@ pub unsafe fn dc_mimefactory_render(mut factory: *mut dc_mimefactory_t) -> libc: strdup(b"v1\x00" as *const u8 as *const libc::c_char), ), ); - placeholdertext = - to_cstring((*factory).context.stock_str(StockMessage::AcSetupMsgBody)); + placeholdertext = (*factory) + .context + .stock_str(StockMessage::AcSetupMsgBody) + .strdup(); } if command == 7 { - let step = to_cstring((*msg).param.get(Param::Arg).unwrap_or_default()); + let step = (*msg).param.get(Param::Arg).unwrap_or_default().strdup(); if strlen(step) > 0 { info!( (*msg).context, @@ -680,7 +682,7 @@ pub unsafe fn dc_mimefactory_render(mut factory: *mut dc_mimefactory_t) -> libc: step, ), ); - let param2 = to_cstring((*msg).param.get(Param::Arg2).unwrap_or_default()); + let param2 = (*msg).param.get(Param::Arg2).unwrap_or_default().strdup(); if strlen(param2) > 0 { mailimf_fields_add( imf_fields, @@ -708,7 +710,7 @@ pub unsafe fn dc_mimefactory_render(mut factory: *mut dc_mimefactory_t) -> libc: ), ); } - let fingerprint = to_cstring((*msg).param.get(Param::Arg3).unwrap_or_default()); + let fingerprint = (*msg).param.get(Param::Arg3).unwrap_or_default().strdup(); if strlen(fingerprint) > 0 { mailimf_fields_add( imf_fields, @@ -722,7 +724,7 @@ pub unsafe fn dc_mimefactory_render(mut factory: *mut dc_mimefactory_t) -> libc: ); } let grpid = match (*msg).param.get(Param::Arg4) { - Some(id) => to_cstring(id), + Some(id) => id.strdup(), None => std::ptr::null_mut(), }; if !grpid.is_null() { @@ -958,25 +960,23 @@ pub unsafe fn dc_mimefactory_render(mut factory: *mut dc_mimefactory_t) -> libc: ) as *mut libc::c_void, ); mailmime_add_part(message, multipart); - let p1: *mut libc::c_char; - let p2: *mut libc::c_char; - if 0 != (*(*factory).msg) - .param - .get_int(Param::GuranteeE2ee) - .unwrap_or_default() + let p1 = if 0 + != (*(*factory).msg) + .param + .get_int(Param::GuranteeE2ee) + .unwrap_or_default() { - p1 = to_cstring((*factory).context.stock_str(StockMessage::EncryptedMsg)); - } else { - p1 = dc_msg_get_summarytext((*factory).msg, 32) - } - p2 = to_cstring( (*factory) .context - .stock_string_repl_str(StockMessage::ReadRcptMailBody, as_str(p1)), - ); - message_text = dc_mprintf(b"%s\r\n\x00" as *const u8 as *const libc::c_char, p2); - free(p1 as *mut libc::c_void); - free(p2 as *mut libc::c_void); + .stock_str(StockMessage::EncryptedMsg) + .into_owned() + } else { + to_string(dc_msg_get_summarytext((*factory).msg, 32)) + }; + let p2 = (*factory) + .context + .stock_string_repl_str(StockMessage::ReadRcptMailBody, p1); + message_text = format!("{}\r\n", p2).strdup(); let human_mime_part: *mut mailmime = build_body_text(message_text); mailmime_add_part(multipart, human_mime_part); message_text2 = @@ -1102,7 +1102,7 @@ unsafe fn get_subject( b"\x00" as *const u8 as *const libc::c_char }; if (*msg).param.get_int(Param::Cmd).unwrap_or_default() == 6 { - ret = to_cstring(context.stock_str(StockMessage::AcSetupMsgSubject)) + ret = context.stock_str(StockMessage::AcSetupMsgSubject).strdup() } else if (*chat).type_0 == DC_CHAT_TYPE_GROUP as libc::c_int || (*chat).type_0 == DC_CHAT_TYPE_VERIFIED_GROUP as libc::c_int { @@ -1165,12 +1165,12 @@ unsafe fn build_body_file( let pathNfilename = (*msg) .param .get(Param::File) - .map(|s| to_cstring(s)) + .map(|s| s.strdup()) .unwrap_or_else(|| std::ptr::null_mut()); let mut mimetype = (*msg) .param .get(Param::MimeType) - .map(|s| to_cstring(s)) + .map(|s| s.strdup()) .unwrap_or_else(|| std::ptr::null_mut()); let suffix = dc_get_filesuffix_lc(pathNfilename); @@ -1189,7 +1189,7 @@ unsafe fn build_body_file( let res = ts .format(&format!("voice-message_%Y-%m-%d_%H-%M-%S.{}", suffix)) .to_string(); - filename_to_send = to_cstring(res); + filename_to_send = res.strdup(); } else if (*msg).type_0 == Viewtype::Audio { filename_to_send = dc_get_filename(pathNfilename) } else if (*msg).type_0 == Viewtype::Image || (*msg).type_0 == Viewtype::Gif { @@ -1329,7 +1329,7 @@ unsafe fn build_body_file( #[allow(non_snake_case)] unsafe fn is_file_size_okay(msg: *const dc_msg_t) -> bool { let mut file_size_okay = true; - let pathNfilename = to_cstring((*msg).param.get(Param::File).unwrap_or_default()); + let pathNfilename = (*msg).param.get(Param::File).unwrap_or_default().strdup(); let bytes = dc_get_filebytes((*msg).context, pathNfilename); if bytes > (49 * 1024 * 1024 / 4 * 3) { diff --git a/src/dc_mimeparser.rs b/src/dc_mimeparser.rs index b0b06cc0b..05c1bec43 100644 --- a/src/dc_mimeparser.rs +++ b/src/dc_mimeparser.rs @@ -1312,9 +1312,8 @@ unsafe fn dc_mimeparser_add_single_part_if_known( } if !filename_parts.is_empty() { free(desired_filename as *mut libc::c_void); - let parts_c = to_cstring(filename_parts); - desired_filename = dc_decode_ext_header(parts_c); - free(parts_c as *mut _); + let parts_c = CString::yolo(filename_parts); + desired_filename = dc_decode_ext_header(parts_c.as_ptr()); } if desired_filename.is_null() { let param = mailmime_find_ct_parameter( diff --git a/src/dc_msg.rs b/src/dc_msg.rs index 66e404680..596347610 100644 --- a/src/dc_msg.rs +++ b/src/dc_msg.rs @@ -65,7 +65,7 @@ pub unsafe fn dc_get_msg_info(context: &Context, msg_id: u32) -> *mut libc::c_ch ret += &format!("Cannot load message #{}.", msg_id as usize); dc_msg_unref(msg); dc_contact_unref(contact_from); - return to_cstring(ret); + return ret.strdup(); } let rawtxt = rawtxt.unwrap(); let rawtxt = dc_truncate_str(rawtxt.trim(), 100000); @@ -92,7 +92,7 @@ pub unsafe fn dc_get_msg_info(context: &Context, msg_id: u32) -> *mut libc::c_ch // device-internal message, no further details needed dc_msg_unref(msg); dc_contact_unref(contact_from); - return to_cstring(ret); + return ret.strdup(); } context @@ -210,7 +210,7 @@ pub unsafe fn dc_get_msg_info(context: &Context, msg_id: u32) -> *mut libc::c_ch dc_msg_unref(msg); dc_contact_unref(contact_from); - to_cstring(ret) + ret.strdup() } pub unsafe fn dc_msg_new_untyped<'a>(context: &'a Context) -> *mut dc_msg_t<'a> { @@ -288,18 +288,17 @@ pub unsafe fn dc_msg_get_filemime(msg: *const dc_msg_t) -> *mut libc::c_char { if !(msg.is_null() || (*msg).magic != 0x11561156i32 as libc::c_uint) { match (*msg).param.get(Param::MimeType) { Some(m) => { - ret = to_cstring(m); + ret = m.strdup(); } None => { if let Some(file) = (*msg).param.get(Param::File) { - let file_c = to_cstring(file); - dc_msg_guess_msgtype_from_suffix(file_c, 0 as *mut Viewtype, &mut ret); + let file_c = CString::yolo(file); + dc_msg_guess_msgtype_from_suffix(file_c.as_ptr(), 0 as *mut Viewtype, &mut ret); if ret.is_null() { ret = dc_strdup( b"application/octet-stream\x00" as *const u8 as *const libc::c_char, ) } - free(file_c as *mut _); } } } @@ -372,9 +371,8 @@ pub unsafe fn dc_msg_get_file(msg: *const dc_msg_t) -> *mut libc::c_char { if !(msg.is_null() || (*msg).magic != 0x11561156i32 as libc::c_uint) { if let Some(file_rel) = (*msg).param.get(Param::File) { - let file_rel_c = to_cstring(file_rel); - file_abs = dc_get_abs_path((*msg).context, file_rel_c); - free(file_rel_c as *mut _); + let file_rel_c = CString::yolo(file_rel); + file_abs = dc_get_abs_path((*msg).context, file_rel_c.as_ptr()); } } if !file_abs.is_null() { @@ -464,12 +462,12 @@ pub fn dc_msg_load_from_db<'a>(msg: *mut dc_msg_t<'a>, context: &'a Context, id: dc_msg_empty(msg); (*msg).id = row.get::<_, i32>(0)? as u32; - (*msg).rfc724_mid = to_cstring(row.get::<_, String>(1)?); + (*msg).rfc724_mid = row.get::<_, String>(1)?.strdup(); (*msg).in_reply_to = match row.get::<_, Option>(2)? { - Some(s) => to_cstring(s), + Some(s) => s.strdup(), None => std::ptr::null_mut(), }; - (*msg).server_folder = to_cstring(row.get::<_, String>(3)?); + (*msg).server_folder = row.get::<_, String>(3)?.strdup(); (*msg).server_uid = row.get(4)?; (*msg).move_state = row.get(5)?; (*msg).chat_id = row.get(6)?; @@ -481,7 +479,7 @@ pub fn dc_msg_load_from_db<'a>(msg: *mut dc_msg_t<'a>, context: &'a Context, id: (*msg).type_0 = row.get(12)?; (*msg).state = row.get(13)?; (*msg).is_dc_message = row.get(14)?; - (*msg).text = to_cstring(row.get::<_, String>(15).unwrap_or_default()); + (*msg).text = row.get::<_, String>(15).unwrap_or_default().strdup(); (*msg).param = row.get::<_, String>(16)?.parse().unwrap_or_default(); (*msg).starred = row.get(17)?; (*msg).hidden = row.get(18)?; @@ -507,10 +505,8 @@ pub unsafe fn dc_get_mime_headers(context: &Context, msg_id: uint32_t) -> *mut l ); if let Some(headers) = headers { - let h = to_cstring(headers); - let res = dc_strdup_keep_null(h); - free(h as *mut _); - res + let h = CString::yolo(headers); + dc_strdup_keep_null(h.as_ptr()) } else { std::ptr::null_mut() } @@ -711,7 +707,7 @@ pub unsafe fn dc_msg_get_text(msg: *const dc_msg_t) -> *mut libc::c_char { } let res = dc_truncate_str(as_str((*msg).text), 30000); - to_cstring(res) + res.strdup() } #[allow(non_snake_case)] @@ -720,9 +716,8 @@ pub unsafe fn dc_msg_get_filename(msg: *const dc_msg_t) -> *mut libc::c_char { if !(msg.is_null() || (*msg).magic != 0x11561156i32 as libc::c_uint) { if let Some(file) = (*msg).param.get(Param::File) { - let file_c = to_cstring(file); - ret = dc_get_filename(file_c); - free(file_c as *mut _); + let file_c = CString::yolo(file); + ret = dc_get_filename(file_c.as_ptr()); } } if !ret.is_null() { @@ -737,9 +732,8 @@ pub unsafe fn dc_msg_get_filebytes(msg: *const dc_msg_t) -> uint64_t { if !(msg.is_null() || (*msg).magic != 0x11561156i32 as libc::c_uint) { if let Some(file) = (*msg).param.get(Param::File) { - let file_c = to_cstring(file); - ret = dc_get_filebytes((*msg).context, file_c); - free(file_c as *mut _); + let file_c = CString::yolo(file); + ret = dc_get_filebytes((*msg).context, file_c.as_ptr()); } } @@ -858,16 +852,19 @@ pub unsafe fn dc_msg_get_summarytext_by_raw( let mut value: *mut libc::c_char = 0 as *mut libc::c_char; let mut append_text: libc::c_int = 1i32; match type_0 { - Viewtype::Image => prefix = to_cstring(context.stock_str(StockMessage::Image)), - Viewtype::Gif => prefix = to_cstring(context.stock_str(StockMessage::Gif)), - Viewtype::Video => prefix = to_cstring(context.stock_str(StockMessage::Video)), - Viewtype::Voice => prefix = to_cstring(context.stock_str(StockMessage::VoiceMessage)), + Viewtype::Image => prefix = context.stock_str(StockMessage::Image).strdup(), + Viewtype::Gif => prefix = context.stock_str(StockMessage::Gif).strdup(), + Viewtype::Video => prefix = context.stock_str(StockMessage::Video).strdup(), + Viewtype::Voice => prefix = context.stock_str(StockMessage::VoiceMessage).strdup(), Viewtype::Audio | Viewtype::File => { if param.get_int(Param::Cmd) == Some(6) { - prefix = to_cstring(context.stock_str(StockMessage::AcSetupMsgSubject)); + prefix = context.stock_str(StockMessage::AcSetupMsgSubject).strdup(); append_text = 0i32 } else { - pathNfilename = to_cstring(param.get(Param::File).unwrap_or_else(|| "ErrFilename")); + pathNfilename = param + .get(Param::File) + .unwrap_or_else(|| "ErrFilename") + .strdup(); value = dc_get_filename(pathNfilename); let label = CString::new( context @@ -888,7 +885,7 @@ pub unsafe fn dc_msg_get_summarytext_by_raw( } _ => { if param.get_int(Param::Cmd) == Some(9) { - prefix = to_cstring(context.stock_str(StockMessage::Location)); + prefix = context.stock_str(StockMessage::Location).strdup(); append_text = 0; } } @@ -1387,7 +1384,7 @@ pub fn dc_rfc724_mid_exists( &[as_str(rfc724_mid)], |row| { if !ret_server_folder.is_null() { - unsafe { *ret_server_folder = to_cstring(row.get::<_, String>(0)?) }; + unsafe { *ret_server_folder = row.get::<_, String>(0)?.strdup() }; } if !ret_server_uid.is_null() { unsafe { *ret_server_uid = row.get(1)? }; diff --git a/src/dc_qr.rs b/src/dc_qr.rs index ac9ad1ffe..5541cd3a4 100644 --- a/src/dc_qr.rs +++ b/src/dc_qr.rs @@ -59,34 +59,34 @@ pub unsafe fn dc_check_qr(context: &Context, qr: *const libc::c_char) -> *mut dc let param: Params = as_str(fragment).parse().expect("invalid params"); addr = param .get(Param::Forwarded) - .map(|s| to_cstring(s)) + .map(|s| s.strdup()) .unwrap_or_else(|| std::ptr::null_mut()); if !addr.is_null() { if let Some(ref name_enc) = param.get(Param::SetLongitude) { let name_r = percent_decode_str(name_enc) .decode_utf8() .expect("invalid name"); - name = to_cstring(name_r); + name = name_r.strdup(); dc_normalize_name(name); } invitenumber = param .get(Param::ProfileImage) - .map(|s| to_cstring(s)) + .map(|s| s.strdup()) .unwrap_or_else(|| std::ptr::null_mut()); auth = param .get(Param::Auth) - .map(|s| to_cstring(s)) + .map(|s| s.strdup()) .unwrap_or_else(|| std::ptr::null_mut()); grpid = param .get(Param::GroupId) - .map(|s| to_cstring(s)) + .map(|s| s.strdup()) .unwrap_or_else(|| std::ptr::null_mut()); if !grpid.is_null() { if let Some(grpname_enc) = param.get(Param::GroupName) { let grpname_r = percent_decode_str(grpname_enc) .decode_utf8() .expect("invalid groupname"); - grpname = to_cstring(grpname_r); + grpname = grpname_r.strdup(); } } } @@ -253,7 +253,7 @@ pub unsafe fn dc_check_qr(context: &Context, qr: *const libc::c_char) -> *mut dc if let Some(peerstate) = peerstate { (*qr_parsed).state = 210i32; let addr_ptr = if let Some(ref addr) = peerstate.addr { - to_cstring(addr) + addr.strdup() } else { std::ptr::null() }; diff --git a/src/dc_receive_imf.rs b/src/dc_receive_imf.rs index 8821cab07..cde7c3615 100644 --- a/src/dc_receive_imf.rs +++ b/src/dc_receive_imf.rs @@ -1210,7 +1210,7 @@ unsafe fn create_or_lookup_group( grpimage = (*part) .param .get(Param::File) - .map(|s| to_cstring(s)) + .map(|s| s.strdup()) .unwrap_or_else(|| std::ptr::null_mut()); ok = 1 } @@ -1407,10 +1407,12 @@ unsafe fn create_or_lookup_adhoc_group( { grpname = dc_strdup(mime_parser.subject) } else { - grpname = to_cstring(context.stock_string_repl_int( - StockMessage::Member, - dc_array_get_cnt(member_ids) as libc::c_int, - )); + grpname = context + .stock_string_repl_int( + StockMessage::Member, + dc_array_get_cnt(member_ids) as libc::c_int, + ) + .strdup(); } chat_id = create_group_record(context, grpid, grpname, create_blocked, 0); @@ -1519,7 +1521,7 @@ fn hex_hash(s: impl AsRef) -> *const libc::c_char { let bytes = s.as_ref().as_bytes(); let result = Sha256::digest(bytes); let result_hex = hex::encode(&result[..8]); - unsafe { to_cstring(result_hex) as *const _ } + unsafe { result_hex.strdup() as *const _ } } #[allow(non_snake_case)] @@ -1604,7 +1606,7 @@ unsafe fn check_verified_properties( let contact = dc_contact_new(context); let verify_fail = |reason: String| { - *failure_reason = to_cstring(format!("{}. See \"Info\" for details.", reason)); + *failure_reason = format!("{}. See \"Info\" for details.", reason).strdup(); warn!(context, 0, "{}", reason); }; @@ -1714,7 +1716,7 @@ unsafe fn set_better_msg>(mime_parser: &dc_mimeparser_t, better_ms carray_get(mime_parser.parts, 0 as libc::c_uint) as *mut dc_mimepart_t; if (*part).type_0 == 10 { free((*part).msg as *mut libc::c_void); - (*part).msg = to_cstring(msg); + (*part).msg = msg.strdup(); } }; } diff --git a/src/dc_securejoin.rs b/src/dc_securejoin.rs index d1910212d..3e908a5c1 100644 --- a/src/dc_securejoin.rs +++ b/src/dc_securejoin.rs @@ -40,7 +40,7 @@ pub unsafe fn dc_get_securejoin_qr( let mut chat = 0 as *mut Chat; let mut group_name = 0 as *mut libc::c_char; let mut group_name_urlencoded = 0 as *mut libc::c_char; - let mut qr = None; + let mut qr: Option = None; dc_ensure_secret_key_exists(context); invitenumber = dc_token_lookup(context, DC_TOKEN_INVITENUMBER, group_chat_id); @@ -64,7 +64,7 @@ pub unsafe fn dc_get_securejoin_qr( free(group_name_urlencoded as *mut libc::c_void); if let Some(qr) = qr { - to_cstring(qr) + qr.strdup() } else { std::ptr::null_mut() } diff --git a/src/dc_simplify.rs b/src/dc_simplify.rs index 34b567105..a95af733b 100644 --- a/src/dc_simplify.rs +++ b/src/dc_simplify.rs @@ -229,7 +229,7 @@ impl dc_simplify_t { } dc_free_splitted_lines(lines); - to_cstring(ret) + ret.strdup() } } diff --git a/src/dc_strencode.rs b/src/dc_strencode.rs index 9bdb5e902..3732d54b0 100644 --- a/src/dc_strencode.rs +++ b/src/dc_strencode.rs @@ -1,4 +1,4 @@ -use std::ffi::CStr; +use std::ffi::{CStr, CString}; use charset::Charset; use mmime::mailmime_decode::*; @@ -710,9 +710,8 @@ unsafe fn print_hex(target: *mut libc::c_char, cur: *const libc::c_char) { assert!(!cur.is_null()); let bytes = std::slice::from_raw_parts(cur as *const _, strlen(cur)); - let raw = to_cstring(format!("={}", &hex::encode_upper(bytes)[..2])); - libc::memcpy(target as *mut _, raw as *const _, 4); - free(raw as *mut libc::c_void); + let raw = CString::yolo(format!("={}", &hex::encode_upper(bytes)[..2])); + libc::memcpy(target as *mut _, raw.as_ptr() as *const _, 4); } #[cfg(test)] diff --git a/src/dc_token.rs b/src/dc_token.rs index 1dd4eccc1..8db5eae34 100644 --- a/src/dc_token.rs +++ b/src/dc_token.rs @@ -42,7 +42,7 @@ pub fn dc_token_lookup( params![namespc as i32, foreign_id as i32], 0, ) - .map(|s| unsafe { to_cstring(s) }) + .map(|s| unsafe { s.strdup() }) .unwrap_or_else(|| std::ptr::null_mut()) } diff --git a/src/dc_tools.rs b/src/dc_tools.rs index 393b66860..5003febc1 100644 --- a/src/dc_tools.rs +++ b/src/dc_tools.rs @@ -178,14 +178,13 @@ pub unsafe fn dc_trim(buf: *mut libc::c_char) { /* the result must be free()'d */ pub unsafe fn dc_strlower(in_0: *const libc::c_char) -> *mut libc::c_char { - to_cstring(to_string(in_0).to_lowercase()) + to_string(in_0).to_lowercase().strdup() } pub unsafe fn dc_strlower_in_place(in_0: *mut libc::c_char) { - let raw = to_cstring(to_string(in_0).to_lowercase()); - assert_eq!(strlen(in_0), strlen(raw)); - memcpy(in_0 as *mut _, raw as *const _, strlen(in_0)); - free(raw as *mut _); + let raw = CString::yolo(to_string(in_0).to_lowercase()); + assert_eq!(strlen(in_0), strlen(raw.as_ptr())); + memcpy(in_0 as *mut _, raw.as_ptr() as *const _, strlen(in_0)); } pub unsafe fn dc_str_contains( @@ -233,7 +232,7 @@ pub unsafe fn dc_binary_to_uc_hex(buf: *const uint8_t, bytes: size_t) -> *mut li let buf = std::slice::from_raw_parts(buf, bytes); let raw = hex::encode_upper(buf); - to_cstring(raw) + raw.strdup() } /* remove all \r characters from string */ @@ -527,7 +526,7 @@ pub unsafe fn dc_str_from_clist( } } - to_cstring(res) + res.strdup() } pub unsafe fn dc_str_to_clist( @@ -1236,10 +1235,8 @@ pub unsafe fn dc_write_file( #[allow(non_snake_case)] pub fn dc_write_file_safe(context: &Context, pathNfilename: impl AsRef, buf: &[u8]) -> bool { let pathNfilename_abs = unsafe { - let n = to_cstring(pathNfilename.as_ref()); - let res = dc_get_abs_path(context, n); - free(n as *mut _); - res + let n = CString::yolo(pathNfilename.as_ref()); + dc_get_abs_path(context, n.as_ptr()) }; if pathNfilename_abs.is_null() { return false; @@ -1287,10 +1284,8 @@ pub unsafe fn dc_read_file( #[allow(non_snake_case)] pub fn dc_read_file_safe(context: &Context, pathNfilename: impl AsRef) -> Option> { let pathNfilename_abs = unsafe { - let n = to_cstring(pathNfilename.as_ref()); - let p = dc_get_abs_path(context, n); - free(n as *mut _); - p + let n = CString::yolo(pathNfilename.as_ref()); + dc_get_abs_path(context, n.as_ptr()) }; if pathNfilename_abs.is_null() { @@ -1523,6 +1518,51 @@ fn os_str_to_c_string_unicode( } } +/// Convenience methods/associated functions for working with [CString] +/// +/// This is helps transitioning from unsafe code. +pub trait CStringExt { + /// Create a new [CString], yolo style + /// + /// This unwrap the result, panicking when there are embedded NULL + /// bytes. + fn yolo>>(t: T) -> CString { + CString::new(t).expect("String contains null byte, can not be CString") + } +} + +impl CStringExt for CString {} + +/// Convenience methods to make transitioning from raw C strings easier. +/// +/// To interact with (legacy) C APIs we often need to convert from +/// Rust strings to raw C strings. This can be clumsy to do correctly +/// and the compiler sometimes allows it in an unsafe way. These +/// methods make it more succinct and help you get it right. +pub trait StrExt { + /// Allocate a new raw C `*char` version of this string. + /// + /// This allocates a new raw C string which must be freed using + /// `free`. It takes care of some common pitfalls with using + /// [CString::as_ptr]. + /// + /// [CString::as_ptr]: std::ffi::CString::as_ptr + /// + /// # Panics + /// + /// This function will panic when the original string contains an + /// interior null byte as this can not be represented in raw C + /// strings. + unsafe fn strdup(&self) -> *mut libc::c_char; +} + +impl> StrExt for T { + unsafe fn strdup(&self) -> *mut libc::c_char { + let tmp = CString::yolo(self.as_ref()); + dc_strdup(tmp.as_ptr()) + } +} + /// Needs to free the result after use! pub unsafe fn to_cstring>(s: S) -> *mut libc::c_char { let cstr = CString::new(s.as_ref()).expect("invalid string converted"); @@ -2085,4 +2125,29 @@ mod tests { let ptr = some_path.as_ptr(); assert_eq!(as_path_unicode(ptr), std::ffi::OsString::from("/some/path")); } + + #[test] + fn test_cstring_yolo() { + assert_eq!(CString::new("hello").unwrap(), CString::yolo("hello")); + } + + #[test] + fn test_strdup_str() { + unsafe { + let s = "hello".strdup(); + let cmp = strcmp(s, b"hello\x00" as *const u8 as *const libc::c_char); + free(s as *mut libc::c_void); + assert_eq!(cmp, 0); + } + } + + #[test] + fn test_strdup_string() { + unsafe { + let s = String::from("hello").strdup(); + let cmp = strcmp(s, b"hello\x00" as *const u8 as *const libc::c_char); + free(s as *mut libc::c_void); + assert_eq!(cmp, 0); + } + } } diff --git a/src/imap.rs b/src/imap.rs index 3d6336299..11a0a8bf8 100644 --- a/src/imap.rs +++ b/src/imap.rs @@ -1,3 +1,4 @@ +use std::ffi::CString; use std::net; use std::sync::{Arc, Condvar, Mutex, RwLock}; use std::time::{Duration, SystemTime}; @@ -5,10 +6,9 @@ use std::time::{Duration, SystemTime}; use crate::constants::*; use crate::context::Context; use crate::dc_loginparam::*; -use crate::dc_tools::to_cstring; +use crate::dc_tools::CStringExt; use crate::oauth2::dc_get_oauth2_access_token; use crate::types::*; -use crate::x::free; pub const DC_IMAP_SEEN: usize = 0x0001; pub const DC_REGENERATE: usize = 0x01; @@ -843,10 +843,8 @@ impl Imap { .expect("missing message id"); if 0 == unsafe { - let message_id_c = to_cstring(message_id); - let res = (self.precheck_imf)(context, message_id_c, folder.as_ref(), cur_uid); - free(message_id_c as *mut _); - res + let message_id_c = CString::yolo(message_id); + (self.precheck_imf)(context, message_id_c.as_ptr(), folder.as_ref(), cur_uid) } { // check passed, go fetch the rest if self.fetch_single_msg(context, &folder, cur_uid) == 0 { diff --git a/src/log.rs b/src/log.rs index 6ab8c4702..e3605d09b 100644 --- a/src/log.rs +++ b/src/log.rs @@ -7,10 +7,9 @@ macro_rules! info { #[allow(unused_unsafe)] unsafe { let formatted = format!($msg, $($args),*); - let formatted_c = $crate::dc_tools::to_cstring(formatted); + let formatted_c = std::ffi::CString::new(formatted).unwrap(); $ctx.call_cb($crate::constants::Event::INFO, $data1 as libc::uintptr_t, - formatted_c as libc::uintptr_t); - libc::free(formatted_c as *mut libc::c_void); + formatted_c.as_ptr() as libc::uintptr_t); }}; } @@ -23,10 +22,9 @@ macro_rules! warn { #[allow(unused_unsafe)] unsafe { let formatted = format!($msg, $($args),*); - let formatted_c = $crate::dc_tools::to_cstring(formatted); + let formatted_c = std::ffi::CString::new(formatted).unwrap(); $ctx.call_cb($crate::constants::Event::WARNING, $data1 as libc::uintptr_t, - formatted_c as libc::uintptr_t); - libc::free(formatted_c as *mut libc::c_void) ; + formatted_c.as_ptr() as libc::uintptr_t); }}; } @@ -39,10 +37,9 @@ macro_rules! error { #[allow(unused_unsafe)] unsafe { let formatted = format!($msg, $($args),*); - let formatted_c = $crate::dc_tools::to_cstring(formatted); + let formatted_c = std::ffi::CString::new(formatted).unwrap(); $ctx.call_cb($crate::constants::Event::ERROR, $data1 as libc::uintptr_t, - formatted_c as libc::uintptr_t); - libc::free(formatted_c as *mut libc::c_void); + formatted_c.as_ptr() as libc::uintptr_t); }}; } @@ -55,9 +52,8 @@ macro_rules! log_event { #[allow(unused_unsafe)] unsafe { let formatted = format!($msg, $($args),*); - let formatted_c = $crate::dc_tools::to_cstring(formatted); + let formatted_c = std::ffi::CString::new(formatted).unwrap(); $ctx.call_cb($event, $data1 as libc::uintptr_t, - formatted_c as libc::uintptr_t); - libc::free(formatted_c as *mut libc::c_void); + formatted_c.as_ptr() as libc::uintptr_t); }}; } diff --git a/src/peerstate.rs b/src/peerstate.rs index b8f9b7724..d7f8009ab 100644 --- a/src/peerstate.rs +++ b/src/peerstate.rs @@ -462,13 +462,11 @@ mod tests { use super::*; use pretty_assertions::assert_eq; - use tempfile::{tempdir, TempDir}; - - use crate::context::*; + use tempfile::TempDir; #[test] fn test_peerstate_save_to_db() { - let ctx = unsafe { create_test_context() }; + let ctx = crate::test_utils::dummy_context(); let addr = "hello@mail.com"; let pub_key = crate::key::Key::from_base64("xsBNBFztUVkBCADYaQl/UOUpRPd32nLRzx8eU0eI+jQEnG+g5anjYA+3oct1rROGl5SygjMULDKdaUy27O3o9Srsti0YjA7uxZnavIqhSopJhFidqY1M1wA9JZa/duucZdNwUGbjGIRsS/4Cjr5+3svscK24hVYub1dvDWXpwUTnj3K6xOEnJdoM+MhCqtSD5+zcJhFc9vyZm9ZTGWUxAhKh0iJTcCD8V6CQ3XZ2z9GruwzZT/FTFovWrz7m3TUI2OdSSHh0eZLRGEoxMCT/vzflAFGAr8ijCaRsEIfqP6FW8uQWnFTqkjxEUCZG6XkeFHB84aj5jqYG/1KCLjL5vEKwfl1tz/WnPhY7ABEBAAHNEDxoZWxsb0BtYWlsLmNvbT7CwIkEEAEIADMCGQEFAlztUVoCGwMECwkIBwYVCAkKCwIDFgIBFiEEgMjHGVbvLXe6ioRROg8oKCvye7gACgkQOg8oKCvye7ijAwf+PTsuawUax9cNPn1bN90H+g9qyHZJMEwKXtUnNaXJxPW3iB7ThhpCiCzsZwP7+l7ArS8tmLeNDw2bENtcf1XCv4wovP2fdXOP3QOUUFX/GdakcTwv7DzC7CO0grB1HtaPhGw/6UX2o2cx2i9xiUf4Givq2MfCbgAW5zloH6WXGPb6yLQYJXxqDIphr4+uZDb+bMAyWHN/DUkAjHrV8nnVki7PMHqzzZpwglalxMX8RGeiGZE39ALJKL/Og87DMFah87/yoxQWGoS7Wqv0XDcCPKoTCPrpk8pOe2KEsq/lz215nefHd4aRpfUX5YCYa8HPvvfPQbGF73uvyQw5w7qjis7ATQRc7VFZAQgAt8ONdnX6KEEQ5Jw6ilJ+LBtY44SP5t0I3eK+goKepgIiKhjGDa+Mntyi4jdhH+HO6kvK5SHMh2sPp4rRO/WKHJwWFySyM1OdyiywhyH0J9R5rBY4vPHsJjf6vSKJdWLWT+ho1fNet2IIC+jVCYli91MAMbRvk6EKVj1nCc+67giOahXEkHt6xxkeCGlOvbw8hxGj1A8+AC1BLms/OR3oc4JMi9O3kq6uG0z9tlUEerac9HVwcjoO1XLe+hJhoT5H+TbnGjPuhuURP3pFiIKHpbRYgUfdSAY0dTObO7t4I5y/drPOrCTnWrBUg2wXAECUhpRKow9/ai2YemLv9KqhhwARAQABwsB2BBgBCAAgBQJc7VFaAhsMFiEEgMjHGVbvLXe6ioRROg8oKCvye7gACgkQOg8oKCvye7jmyggAhs4QzCzIbT2OsAReBxkxtm0AI+g1HZ1KFKof5NDHfgv9C/Qu1I8mKEjlZzA4qFyPmLqntgwJ0RuFy6gLbljZBNCFO7vB478AhYtnWjuKZmA40HUPwcB1hEJ31c42akzfUbioY1TLLepngdsJg7Cm8O+rhI9+1WRA66haJDgFs793SVUDyJh8f9NX50l5zR87/bsV30CFSw0q4OSSy9VI/z+2g5khn1LnuuOrCfFnYIPYtJED1BfkXkosxGlgbzy79VvGmI9d23x4atDK7oBPCzIj+lP8sytJ0u3HOguXi9OgDitKy+Pt1r8gH8frdktMJr5Ts6DW+tIn2vR23KR8aA==", KeyType::Public).unwrap(); @@ -506,26 +504,4 @@ mod tests { ctx: Context, dir: TempDir, } - - unsafe extern "C" fn cb( - _context: &Context, - _event: Event, - _data1: libc::uintptr_t, - _data2: libc::uintptr_t, - ) -> libc::uintptr_t { - 0 - } - - unsafe fn create_test_context() -> TestContext { - let mut ctx = dc_context_new(Some(cb), std::ptr::null_mut(), None); - let dir = tempdir().unwrap(); - let dbfile = dir.path().join("db.sqlite"); - assert!( - dc_open(&mut ctx, dbfile.to_str().unwrap(), None), - "Failed to open {}", - dbfile.to_str().unwrap() - ); - - TestContext { ctx: ctx, dir: dir } - } } diff --git a/src/sql.rs b/src/sql.rs index 08382dc9e..2264e3c0e 100644 --- a/src/sql.rs +++ b/src/sql.rs @@ -10,7 +10,6 @@ use crate::dc_tools::*; use crate::error::{Error, Result}; use crate::param::*; use crate::peerstate::*; -use crate::x::*; const DC_OPEN_READONLY: usize = 0x01; @@ -1049,9 +1048,8 @@ pub fn housekeeping(context: &Context) { entry.file_name() ); unsafe { - let path = to_cstring(entry.path().to_str().unwrap()); - dc_delete_file(context, path); - free(path as *mut _); + let path = entry.path().to_c_string().unwrap(); + dc_delete_file(context, path.as_ptr()); } } } diff --git a/tests/stress.rs b/tests/stress.rs index c5a56f4f2..38c0723e3 100644 --- a/tests/stress.rs +++ b/tests/stress.rs @@ -671,7 +671,7 @@ fn test_encryption_decryption() { assert!(ctext.starts_with("-----BEGIN PGP MESSAGE-----")); let ctext_signed_bytes = ctext.len(); - let ctext_signed = to_cstring(ctext); + let ctext_signed = CString::yolo(ctext); let ctext = dc_pgp_pk_encrypt( original_text as *const libc::c_void, @@ -684,7 +684,7 @@ fn test_encryption_decryption() { assert!(ctext.starts_with("-----BEGIN PGP MESSAGE-----")); let ctext_unsigned_bytes = ctext.len(); - let ctext_unsigned = to_cstring(ctext); + let ctext_unsigned = CString::yolo(ctext); let mut keyring = Keyring::default(); keyring.add_owned(private_key); @@ -698,7 +698,7 @@ fn test_encryption_decryption() { let mut valid_signatures: HashSet = Default::default(); let plain = dc_pgp_pk_decrypt( - ctext_signed as *const _, + ctext_signed.as_ptr() as *const _, ctext_signed_bytes, &keyring, &public_keyring, @@ -713,7 +713,7 @@ fn test_encryption_decryption() { let empty_keyring = Keyring::default(); let plain = dc_pgp_pk_decrypt( - ctext_signed as *const _, + ctext_signed.as_ptr() as *const _, ctext_signed_bytes, &keyring, &empty_keyring, @@ -726,7 +726,7 @@ fn test_encryption_decryption() { valid_signatures.clear(); let plain = dc_pgp_pk_decrypt( - ctext_signed as *const _, + ctext_signed.as_ptr() as *const _, ctext_signed_bytes, &keyring, &public_keyring2, @@ -741,7 +741,7 @@ fn test_encryption_decryption() { public_keyring2.add_ref(&public_key); let plain = dc_pgp_pk_decrypt( - ctext_signed as *const _, + ctext_signed.as_ptr() as *const _, ctext_signed_bytes, &keyring, &public_keyring2, @@ -754,7 +754,7 @@ fn test_encryption_decryption() { valid_signatures.clear(); let plain = dc_pgp_pk_decrypt( - ctext_unsigned as *const _, + ctext_unsigned.as_ptr() as *const _, ctext_unsigned_bytes, &keyring, &public_keyring, @@ -762,7 +762,6 @@ fn test_encryption_decryption() { ) .unwrap(); - free(ctext_unsigned as *mut _); assert_eq!(std::str::from_utf8(&plain).unwrap(), as_str(original_text),); valid_signatures.clear(); @@ -773,7 +772,7 @@ fn test_encryption_decryption() { public_keyring.add_ref(&public_key); let plain = dc_pgp_pk_decrypt( - ctext_signed as *const _, + ctext_signed.as_ptr() as *const _, ctext_signed_bytes, &keyring, &public_keyring, @@ -781,7 +780,6 @@ fn test_encryption_decryption() { ) .unwrap(); - free(ctext_signed as *mut _); assert_eq!(std::str::from_utf8(&plain).unwrap(), as_str(original_text),); } } @@ -808,7 +806,7 @@ unsafe fn create_test_context() -> TestContext { assert!( dc_open(&mut ctx, dbfile.to_str().unwrap(), None), "Failed to open {}", - dbfile.to_str().unwrap() + dbfile.display() ); TestContext { ctx: ctx, dir: dir } } @@ -931,29 +929,24 @@ fn test_stress_tests() { fn test_get_contacts() { unsafe { let context = create_test_context(); - let name = to_cstring("some2"); - let contacts = dc_get_contacts(&context.ctx, 0, name); + let name = CString::yolo("some2"); + let contacts = dc_get_contacts(&context.ctx, 0, name.as_ptr()); assert_eq!(dc_array_get_cnt(contacts), 0); dc_array_unref(contacts); - free(name as *mut _); - let name = to_cstring("bob"); - let email = to_cstring("bob@mail.de"); - let id = dc_create_contact(&context.ctx, name, email); + let name = CString::yolo("bob"); + let email = CString::yolo("bob@mail.de"); + let id = dc_create_contact(&context.ctx, name.as_ptr(), email.as_ptr()); assert_ne!(id, 0); - let contacts = dc_get_contacts(&context.ctx, 0, name); + let contacts = dc_get_contacts(&context.ctx, 0, name.as_ptr()); assert_eq!(dc_array_get_cnt(contacts), 1); dc_array_unref(contacts); - let name2 = to_cstring("alice"); - let contacts = dc_get_contacts(&context.ctx, 0, name2); + let name2 = CString::yolo("alice"); + let contacts = dc_get_contacts(&context.ctx, 0, name2.as_ptr()); assert_eq!(dc_array_get_cnt(contacts), 0); dc_array_unref(contacts); - - free(name as *mut _); - free(name2 as *mut _); - free(email as *mut _); } } @@ -961,12 +954,10 @@ fn test_get_contacts() { fn test_chat() { unsafe { let context = create_test_context(); - let name = to_cstring("bob"); - let email = to_cstring("bob@mail.de"); + let name = CString::yolo("bob"); + let email = CString::yolo("bob@mail.de"); - let contact1 = dc_create_contact(&context.ctx, name, email); - free(name as *mut _); - free(email as *mut _); + let contact1 = dc_create_contact(&context.ctx, name.as_ptr(), email.as_ptr()); assert_ne!(contact1, 0); let chat_id = dc_create_chat_by_contact_id(&context.ctx, contact1);