Remove to_cstring() naming convention ambiguity

Add a trait for str.strdup() to replace to_cstring() which avoid the
signature ambiguity with .to_string().

Also instruduce CString::yolo() as a shortcut to
CString::new().unwrap() and use it whenever the variable does can be
deallocated by going out of scope.  This is less error prone.

Use some Path.to_c_string() functions where possible.
This commit is contained in:
Floris Bruynooghe
2019-08-01 00:08:23 +02:00
committed by Floris Bruynooghe
parent e7428887d0
commit b6b0849bce
31 changed files with 395 additions and 381 deletions

View File

@@ -15,6 +15,7 @@ use num_traits::{FromPrimitive, ToPrimitive};
use std::ptr; use std::ptr;
use std::str::FromStr; use std::str::FromStr;
use deltachat::dc_tools::StrExt;
use deltachat::*; use deltachat::*;
// TODO: constants // TODO: constants
@@ -126,10 +127,7 @@ pub unsafe extern "C" fn dc_get_config(
let context = &*context; let context = &*context;
match config::Config::from_str(dc_tools::as_str(key)) { match config::Config::from_str(dc_tools::as_str(key)) {
Ok(key) => { Ok(key) => context.get_config(key).unwrap_or_default().strdup(),
let value = context.get_config(key).unwrap_or_default();
dc_tools::to_cstring(value)
}
Err(_) => std::ptr::null_mut(), 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 addr = dc_tools::to_string(addr);
let redirect = dc_tools::to_string(redirect); let redirect = dc_tools::to_string(redirect);
match oauth2::dc_get_oauth2_url(context, addr, 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(), None => std::ptr::null_mut(),
} }
} }

View File

@@ -147,7 +147,7 @@ unsafe fn poke_spec(context: &Context, spec: *const libc::c_char) -> libc::c_int
} else { } else {
current_block = 7149356873433890176; current_block = 7149356873433890176;
} }
real_spec = to_cstring(rs.unwrap_or_default()); real_spec = rs.unwrap_or_default().strdup();
} }
match current_block { match current_block {
8522321847195001863 => {} 8522321847195001863 => {}
@@ -184,11 +184,10 @@ unsafe fn poke_spec(context: &Context, spec: *const libc::c_char) -> libc::c_int
if name.ends_with(".eml") { if name.ends_with(".eml") {
let path_plus_name = format!("{}/{}", as_str(real_spec), name); let path_plus_name = format!("{}/{}", as_str(real_spec), name);
info!(context, 0, "Import: {}", path_plus_name); info!(context, 0, "Import: {}", path_plus_name);
let path_plus_name_c = to_cstring(path_plus_name); let path_plus_name_c = CString::yolo(path_plus_name);
if 0 != dc_poke_eml_file(context, path_plus_name_c) { if 0 != dc_poke_eml_file(context, path_plus_name_c.as_ptr()) {
read_cnt += 1 read_cnt += 1
} }
free(path_plus_name_c as *mut _);
} }
} }
current_block = 1622411330066726685; 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() { let arg1_c = if arg1.is_empty() {
std::ptr::null() std::ptr::null()
} else { } else {
to_cstring(arg1) as *const _ arg1.strdup() as *const _
}; };
let arg2 = args.next().unwrap_or_default(); let arg2 = args.next().unwrap_or_default();
let arg2_c = if arg2.is_empty() { let arg2_c = if arg2.is_empty() {
std::ptr::null() std::ptr::null()
} else { } else {
to_cstring(arg2) as *const _ arg2.strdup() as *const _
}; };
match arg0 { 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!(!sel_chat.is_null(), "No chat selected.");
ensure!(!arg1.is_empty(), "No message text given."); 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."); println!("Message sent.");
free(msg as *mut _);
} else { } else {
free(msg as *mut _);
bail!("Sending failed."); bail!("Sending failed.");
} }
} }

View File

@@ -481,7 +481,7 @@ unsafe fn handle_cmd(line: &str, ctx: Arc<RwLock<Context>>) -> Result<ExitResult
let arg1_c = if arg1.is_empty() { let arg1_c = if arg1.is_empty() {
std::ptr::null() std::ptr::null()
} else { } else {
to_cstring(arg1) arg1.strdup()
}; };
match arg0 { match arg0 {

View File

@@ -256,7 +256,7 @@ impl<'a> Chatlist<'a> {
let mut ret = dc_lot_new(); let mut ret = dc_lot_new();
if index >= self.ids.len() { if index >= self.ids.len() {
(*ret).text2 = to_cstring("ErrBadChatlistIndex"); (*ret).text2 = "ErrBadChatlistIndex".strdup();
return ret; return ret;
} }
@@ -267,7 +267,7 @@ impl<'a> Chatlist<'a> {
chat = dc_chat_new(self.context); chat = dc_chat_new(self.context);
let chat_to_delete = chat; let chat_to_delete = chat;
if !dc_chat_load_from_db(chat, self.ids[index].0) { 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); dc_chat_unref(chat_to_delete);
return ret; return ret;
@@ -293,7 +293,7 @@ impl<'a> Chatlist<'a> {
if (*chat).id == DC_CHAT_ID_ARCHIVED_LINK as u32 { if (*chat).id == DC_CHAT_ID_ARCHIVED_LINK as u32 {
(*ret).text2 = dc_strdup(0 as *const libc::c_char) (*ret).text2 = dc_strdup(0 as *const libc::c_char)
} else if lastmsg.is_null() || (*lastmsg).from_id == DC_CONTACT_ID_SELF as u32 { } 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 { } else {
dc_lot_fill(ret, lastmsg, chat, lastcontact, self.context); dc_lot_fill(ret, lastmsg, chat, lastcontact, self.context);
} }

View File

@@ -1,3 +1,5 @@
use std::ffi::CString;
use strum::{EnumProperty, IntoEnumIterator}; use strum::{EnumProperty, IntoEnumIterator};
use strum_macros::{AsRefStr, Display, EnumIter, EnumProperty, EnumString}; use strum_macros::{AsRefStr, Display, EnumIter, EnumProperty, EnumString};
@@ -72,10 +74,8 @@ impl Context {
let rel_path = self.sql.get_config(self, key); let rel_path = self.sql.get_config(self, key);
rel_path.map(|p| { rel_path.map(|p| {
let v = unsafe { let v = unsafe {
let n = to_cstring(p); let n = CString::yolo(p);
let res = dc_get_abs_path(self, n); dc_get_abs_path(self, n.as_ptr())
free(n as *mut libc::c_void);
res
}; };
let r = to_string(v); let r = to_string(v);
unsafe { free(v as *mut _) }; unsafe { free(v as *mut _) };

View File

@@ -483,7 +483,7 @@ pub unsafe fn dc_get_info(context: &Context) -> *mut libc::c_char {
fingerprint_str, fingerprint_str,
); );
to_cstring(res) res.strdup()
} }
pub unsafe fn dc_get_version_str() -> *mut libc::c_char { pub unsafe fn dc_get_version_str() -> *mut libc::c_char {

View File

@@ -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 dc_array_t::Locations(v) = &*array {
if let Some(s) = &v[index].marker { if let Some(s) = &v[index].marker {
to_cstring(s) s.strdup()
} else { } else {
std::ptr::null_mut() std::ptr::null_mut()
} }
@@ -375,7 +375,7 @@ pub unsafe fn dc_array_get_string(
res + sep + &n.to_string() res + sep + &n.to_string()
} }
}); });
to_cstring(res) res.strdup()
} else { } else {
panic!("Attempt to get string from array of other type"); panic!("Attempt to get string from array of other type");
} }

View File

@@ -137,14 +137,8 @@ pub fn dc_chat_load_from_db(chat: *mut Chat, chat_id: u32) -> bool {
c.id = row.get(0)?; c.id = row.get(0)?;
c.type_0 = row.get(1)?; c.type_0 = row.get(1)?;
c.name = { c.name = unsafe { row.get::<_, String>(2)?.strdup() };
let raw: String = row.get(2)?; c.grpid = unsafe { row.get::<_, String>(3)?.strdup() };
unsafe { to_cstring(raw) }
};
c.grpid = {
let raw: String = row.get(3)?;
unsafe { to_cstring(raw) }
};
c.param = row.get::<_, String>(4)?.parse().unwrap_or_default(); c.param = row.get::<_, String>(4)?.parse().unwrap_or_default();
c.archived = row.get(5)?; 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 { match c.id {
1 => unsafe { 1 => unsafe {
free((*chat).name as *mut libc::c_void); 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 { 6 => unsafe {
free((*chat).name as *mut libc::c_void); free((*chat).name as *mut libc::c_void);
let tempname = (*chat).context.stock_str(StockMessage::ArchivedChats); let tempname = (*chat).context.stock_str(StockMessage::ArchivedChats);
let cnt = dc_get_archived_cnt((*chat).context); let cnt = dc_get_archived_cnt((*chat).context);
(*chat).name = to_cstring(format!("{} ({})", tempname, cnt)); (*chat).name = format!("{} ({})", tempname, cnt).strdup();
}, },
5 => unsafe { 5 => unsafe {
free((*chat).name as *mut libc::c_void); 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) { if unsafe { &(*chat).param }.exists(Param::Selftalk) {
unsafe { unsafe {
free((*chat).name as *mut libc::c_void); free((*chat).name as *mut libc::c_void);
(*chat).name = (*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) let mut pathNfilename = (*msg)
.param .param
.get(Param::File) .get(Param::File)
.map(|s| to_cstring(s)) .map(|s| s.strdup())
.unwrap_or_else(|| std::ptr::null_mut()); .unwrap_or_else(|| std::ptr::null_mut());
if pathNfilename.is_null() { if pathNfilename.is_null() {
error!( error!(
@@ -516,16 +513,15 @@ unsafe fn prepare_msg_raw(
if from.is_none() { if from.is_none() {
error!(context, 0, "Cannot send message, not configured.",); error!(context, 0, "Cannot send message, not configured.",);
} else { } else {
let from_c = to_cstring(from.unwrap()); let from_c = CString::yolo(from.unwrap());
new_rfc724_mid = dc_create_outgoing_rfc724_mid( new_rfc724_mid = dc_create_outgoing_rfc724_mid(
if (*chat).type_0 == 120 || (*chat).type_0 == 130 { if (*chat).type_0 == 120 || (*chat).type_0 == 130 {
(*chat).grpid (*chat).grpid
} else { } else {
0 as *mut libc::c_char 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 (*chat).type_0 == DC_CHAT_TYPE_SINGLE {
if let Some(id) = context.sql.query_row_col( 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!=?);", FROM msgs WHERE chat_id=? AND from_id!=?);",
params![(*chat).id as i32, 1], params![(*chat).id as i32, 1],
|row| { |row| {
*parent_rfc724_mid = to_cstring(row.get::<_, String>(0)?); *parent_rfc724_mid = row.get::<_, String>(0)?.strdup();
*parent_in_reply_to = to_cstring(row.get::<_, String>(1)?); *parent_in_reply_to = row.get::<_, String>(1)?.strdup();
*parent_references = to_cstring(row.get::<_, String>(2)?); *parent_references = row.get::<_, String>(2)?.strdup();
Ok(()) Ok(())
}, },
) )
@@ -807,9 +803,9 @@ unsafe fn get_parent_mime_headers(
FROM msgs WHERE chat_id=? AND from_id==?);", FROM msgs WHERE chat_id=? AND from_id==?);",
params![(*chat).id as i32, 1], params![(*chat).id as i32, 1],
|row| { |row| {
*parent_rfc724_mid = to_cstring(row.get::<_, String>(0)?); *parent_rfc724_mid = row.get::<_, String>(0)?.strdup();
*parent_in_reply_to = to_cstring(row.get::<_, String>(1)?); *parent_in_reply_to = row.get::<_, String>(1)?.strdup();
*parent_references = to_cstring(row.get::<_, String>(2)?); *parent_references = row.get::<_, String>(2)?.strdup();
Ok(()) 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) let mut pathNfilename = (*msg)
.param .param
.get(Param::File) .get(Param::File)
.map(|s| to_cstring(s)) .map(|s| s.strdup())
.unwrap_or_else(|| std::ptr::null_mut()); .unwrap_or_else(|| std::ptr::null_mut());
if pathNfilename.is_null() { if pathNfilename.is_null() {
OK_TO_CONTINUE = false; OK_TO_CONTINUE = false;
@@ -1620,12 +1616,14 @@ pub unsafe fn dc_add_contact_to_chat_ex(
if OK_TO_CONTINUE { if OK_TO_CONTINUE {
if (*chat).param.get_int(Param::Unpromoted).unwrap_or_default() == 0 { if (*chat).param.get_int(Param::Unpromoted).unwrap_or_default() == 0 {
(*msg).type_0 = Viewtype::Text; (*msg).type_0 = Viewtype::Text;
(*msg).text = to_cstring(context.stock_system_msg( (*msg).text = context
.stock_system_msg(
StockMessage::MsgAddMember, StockMessage::MsgAddMember,
as_str((*contact).addr), as_str((*contact).addr),
"", "",
DC_CONTACT_ID_SELF as uint32_t, DC_CONTACT_ID_SELF as uint32_t,
)); )
.strdup();
(*msg).param.set_int(Param::Cmd, 4); (*msg).param.set_int(Param::Cmd, 4);
if !(*contact).addr.is_null() { if !(*contact).addr.is_null() {
(*msg).param.set(Param::Arg, as_str((*contact).addr)); (*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; (*msg).type_0 = Viewtype::Text;
if (*contact).id == 1 as libc::c_uint { if (*contact).id == 1 as libc::c_uint {
dc_set_group_explicitly_left(context, (*chat).grpid); dc_set_group_explicitly_left(context, (*chat).grpid);
(*msg).text = to_cstring(context.stock_system_msg( (*msg).text = context
.stock_system_msg(
StockMessage::MsgGroupLeft, StockMessage::MsgGroupLeft,
"", "",
"", "",
DC_CONTACT_ID_SELF as u32, DC_CONTACT_ID_SELF as u32,
)); )
.strdup();
} else { } else {
(*msg).text = to_cstring(context.stock_system_msg( (*msg).text = context
.stock_system_msg(
StockMessage::MsgDelMember, StockMessage::MsgDelMember,
as_str((*contact).addr), as_str((*contact).addr),
"", "",
DC_CONTACT_ID_SELF as u32, DC_CONTACT_ID_SELF as u32,
)); )
.strdup();
} }
(*msg).param.set_int(Param::Cmd, 5); (*msg).param.set_int(Param::Cmd, 5);
if !(*contact).addr.is_null() { 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 { if (*chat).param.get_int(Param::Unpromoted).unwrap_or_default() == 0 {
(*msg).type_0 = Viewtype::Text; (*msg).type_0 = Viewtype::Text;
(*msg).text = to_cstring(context.stock_system_msg( (*msg).text = context
.stock_system_msg(
StockMessage::MsgGrpName, StockMessage::MsgGrpName,
as_str((*chat).name), as_str((*chat).name),
as_str(new_name), as_str(new_name),
DC_CONTACT_ID_SELF as u32, DC_CONTACT_ID_SELF as u32,
)); )
.strdup();
(*msg).param.set_int(Param::Cmd, 2); (*msg).param.set_int(Param::Cmd, 2);
if !(*chat).name.is_null() { if !(*chat).name.is_null() {
(*msg).param.set(Param::Arg, as_str((*chat).name)); (*msg).param.set(Param::Arg, as_str((*chat).name));
@@ -1918,7 +1922,8 @@ pub unsafe fn dc_set_chat_profile_image(
(*msg).param.set_int(Param::Cmd, 3); (*msg).param.set_int(Param::Cmd, 3);
(*msg).param.set(Param::Arg, as_str(new_image_rel)); (*msg).param.set(Param::Arg, as_str(new_image_rel));
(*msg).type_0 = Viewtype::Text; (*msg).type_0 = Viewtype::Text;
(*msg).text = to_cstring(context.stock_system_msg( (*msg).text = context
.stock_system_msg(
if !new_image_rel.is_null() { if !new_image_rel.is_null() {
StockMessage::MsgGrpImgChanged StockMessage::MsgGrpImgChanged
} else { } else {
@@ -1927,7 +1932,8 @@ pub unsafe fn dc_set_chat_profile_image(
"", "",
"", "",
DC_CONTACT_ID_SELF as uint32_t, DC_CONTACT_ID_SELF as uint32_t,
)); )
.strdup();
(*msg).id = dc_send_msg(context, chat_id, msg); (*msg).id = dc_send_msg(context, chat_id, msg);
context.call_cb( context.call_cb(
Event::MSGS_CHANGED, 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(); let mut ret: *mut libc::c_char = std::ptr::null_mut();
if (*chat).type_0 == 100 && (*chat).param.exists(Param::Selftalk) { 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 { } else if (*chat).type_0 == 100 {
let ret_raw: String = (*chat) let ret_raw: String = (*chat)
.context .context
@@ -2108,17 +2117,16 @@ pub unsafe fn dc_chat_get_subtitle(chat: *const Chat) -> *mut libc::c_char {
0, 0,
) )
.unwrap_or_else(|| "Err".into()); .unwrap_or_else(|| "Err".into());
ret = to_cstring(ret_raw); ret = ret_raw.strdup();
} else if (*chat).type_0 == 120 || (*chat).type_0 == 130 { } else if (*chat).type_0 == 120 || (*chat).type_0 == 130 {
if (*chat).id == 1 { if (*chat).id == 1 {
ret = to_cstring((*chat).context.stock_str(StockMessage::DeadDrop)); ret = (*chat).context.stock_str(StockMessage::DeadDrop).strdup();
} else { } else {
let cnt = dc_get_chat_contact_cnt((*chat).context, (*chat).id); let cnt = dc_get_chat_contact_cnt((*chat).context, (*chat).id);
ret = to_cstring( ret = (*chat)
(*chat)
.context .context
.stock_string_repl_int(StockMessage::Member, cnt), .stock_string_repl_int(StockMessage::Member, cnt)
); .strdup();
} }
} }
return if !ret.is_null() { 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 contacts: *mut dc_array_t = 0 as *mut dc_array_t;
let mut contact: *mut dc_contact_t = 0 as *mut dc_contact_t; let mut contact: *mut dc_contact_t = 0 as *mut dc_contact_t;
if !(chat.is_null() || (*chat).magic != 0xc4a7c4a7u32) { 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 { if !image_rel.is_null() && 0 != *image_rel.offset(0isize) as libc::c_int {
image_abs = dc_get_abs_path((*chat).context, image_rel) image_abs = dc_get_abs_path((*chat).context, image_rel)
} else if (*chat).type_0 == 100i32 { } else if (*chat).type_0 == 100i32 {

View File

@@ -1102,14 +1102,14 @@ unsafe fn moz_autoconfigure(
tag_config: 0, tag_config: 0,
}; };
let url_c = to_cstring(url); let url_c = url.strdup();
let xml_raw = read_autoconf_file(context, url_c); let xml_raw = read_autoconf_file(context, url_c);
free(url_c as *mut libc::c_void); free(url_c as *mut libc::c_void);
if xml_raw.is_null() { if xml_raw.is_null() {
return None; return None;
} }
moz_ac.in_emaillocalpart = to_cstring(&param_in.addr); moz_ac.in_emaillocalpart = param_in.addr.strdup();
let p = strchr(moz_ac.in_emaillocalpart, '@' as i32); let p = strchr(moz_ac.in_emaillocalpart, '@' as i32);
if p.is_null() { 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 moz_ac: *mut moz_autoconfigure_t = userdata as *mut moz_autoconfigure_t;
let mut val: *mut libc::c_char = dc_strdup(text); let mut val: *mut libc::c_char = dc_strdup(text);
dc_trim(val); dc_trim(val);
let addr = to_cstring(&(*moz_ac).in_0.addr); let addr = (*moz_ac).in_0.addr.strdup();
dc_str_replace( dc_str_replace(
&mut val, &mut val,
b"%EMAILADDRESS%\x00" as *const u8 as *const libc::c_char, 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() .send()
.and_then(|mut res| res.text()) .and_then(|mut res| res.text())
{ {
Ok(res) => unsafe { to_cstring(res) }, Ok(res) => unsafe { res.strdup() },
Err(_err) => { Err(_err) => {
info!(context, 0, "Can\'t read file.",); info!(context, 0, "Can\'t read file.",);
@@ -1322,7 +1322,7 @@ unsafe fn outlk_autodiscover(
) -> Option<dc_loginparam_t> { ) -> Option<dc_loginparam_t> {
let current_block: u64; let current_block: u64;
let mut xml_raw: *mut libc::c_char = 0 as *mut libc::c_char; 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 { let mut outlk_ad = outlk_autodiscover_t {
in_0: param_in, in_0: param_in,
out: dc_loginparam_new(), out: dc_loginparam_new(),

View File

@@ -278,14 +278,13 @@ pub unsafe fn dc_contact_load_from_db(
if contact_id == 1 as libc::c_uint { if contact_id == 1 as libc::c_uint {
(*contact).id = contact_id; (*contact).id = contact_id;
(*contact).name = to_cstring((*contact).context.stock_str(StockMessage::SelfMsg)); (*contact).name = (*contact).context.stock_str(StockMessage::SelfMsg).strdup();
(*contact).addr = to_cstring( (*contact).addr = (*contact)
(*contact)
.context .context
.sql .sql
.get_config((*contact).context, "configured_addr") .get_config((*contact).context, "configured_addr")
.unwrap_or_default(), .unwrap_or_default()
); .strdup();
true true
} else { } else {
sql.query_row( sql.query_row(
@@ -293,11 +292,11 @@ pub unsafe fn dc_contact_load_from_db(
params![contact_id as i32], params![contact_id as i32],
|row| { |row| {
(*contact).id = contact_id; (*contact).id = contact_id;
(*contact).name = to_cstring(row.get::<_, String>(0)?); (*contact).name = row.get::<_, String>(0)?.strdup();
(*contact).addr = to_cstring(row.get::<_, String>(1)?); (*contact).addr = row.get::<_, String>(1)?.strdup();
(*contact).origin = row.get(2)?; (*contact).origin = row.get(2)?;
(*contact).blocked = row.get::<_, Option<i32>>(3)?.unwrap_or_default(); (*contact).blocked = row.get::<_, Option<i32>>(3)?.unwrap_or_default();
(*contact).authname = to_cstring(row.get::<_, String>(4)?); (*contact).authname = row.get::<_, String>(4)?.strdup();
Ok(()) Ok(())
} }
).is_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_verified as *mut libc::c_void);
free(fingerprint_other_unverified as *mut libc::c_void); free(fingerprint_other_unverified as *mut libc::c_void);
to_cstring(ret) ret.strdup()
} }
unsafe fn cat_fingerprint( 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 { if unsafe { (*contact).id } == 1 {
let context = unsafe { (*contact) }.context; let context = unsafe { (*contact) }.context;
if let Some(avatar) = context.get_config(config::Config::Selfavatar) { 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 // TODO: else get image_abs from contact param

View File

@@ -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); dc_saxparser_parse(&mut saxparser, buf_terminated);
free(dehtml.last_href as *mut libc::c_void); free(dehtml.last_href as *mut libc::c_void);
to_cstring(dehtml.strbuilder) dehtml.strbuilder.strdup()
} }
unsafe fn dehtml_text_cb( unsafe fn dehtml_text_cb(

View File

@@ -177,16 +177,12 @@ pub unsafe fn dc_e2ee_encrypt(
let p = peerstates[i as usize] let p = peerstates[i as usize]
.render_gossip_header(min_verified as usize); .render_gossip_header(min_verified as usize);
if p.is_some() { if let Some(header) = p {
let header = to_cstring(p.unwrap());
mailimf_fields_add( mailimf_fields_add(
imffields_encrypted, imffields_encrypted,
mailimf_field_new_custom( mailimf_field_new_custom(
strdup( "Autocrypt-Gossip".strdup(),
b"Autocrypt-Gossip\x00" as *const u8 header.strdup(),
as *const libc::c_char,
),
header,
), ),
); );
} }
@@ -296,7 +292,7 @@ pub unsafe fn dc_e2ee_encrypt(
sign_key.as_ref(), sign_key.as_ref(),
) { ) {
let ctext_bytes = ctext_v.len(); let ctext_bytes = ctext_v.len();
let ctext = to_cstring(ctext_v); let ctext = ctext_v.strdup();
(*helper).cdata_to_free = ctext as *mut _; (*helper).cdata_to_free = ctext as *mut _;
/* create MIME-structure that will contain the encrypted text */ /* create MIME-structure that will contain the encrypted text */
@@ -354,13 +350,11 @@ pub unsafe fn dc_e2ee_encrypt(
14181132614457621749 => {} 14181132614457621749 => {}
_ => { _ => {
let aheader = Aheader::new(addr, public_key, prefer_encrypt); let aheader = Aheader::new(addr, public_key, prefer_encrypt);
let rendered = to_cstring(aheader.to_string());
mailimf_fields_add( mailimf_fields_add(
imffields_unprotected, imffields_unprotected,
mailimf_field_new_custom( mailimf_field_new_custom(
strdup(b"Autocrypt\x00" as *const u8 as *const libc::c_char), "Autocrypt".strdup(),
rendered, aheader.to_string().strdup(),
), ),
); );
} }

View File

@@ -515,7 +515,7 @@ pub unsafe fn dc_normalize_setup_code(
p1 = p1.offset(1); p1 = p1.offset(1);
} }
to_cstring(out) out.strdup()
} }
#[allow(non_snake_case)] #[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 success: libc::c_int = 0;
let mut ongoing_allocated_here: libc::c_int = 0; let mut ongoing_allocated_here: libc::c_int = 0;
let what: libc::c_int; 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)) { if !(0 == dc_alloc_ongoing(context)) {
ongoing_allocated_here = 1; ongoing_allocated_here = 1;
what = (*job).param.get_int(Param::Cmd).unwrap_or_default(); what = (*job).param.get_int(Param::Cmd).unwrap_or_default();
param1 = to_cstring((*job).param.get(Param::Arg).unwrap_or_default()); let param1 = CString::yolo((*job).param.get(Param::Arg).unwrap_or_default());
param2 = to_cstring((*job).param.get(Param::Arg2).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.",); error!(context, 0, "No Import/export dir/file given.",);
} else { } else {
info!(context, 0, "Import/export process started.",); 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; current_block = 3568988166330621280;
} else { } else {
dc_create_folder(context, param1); dc_create_folder(context, param1.as_ptr());
current_block = 4495394744059808450; current_block = 4495394744059808450;
} }
} else { } 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; current_block = 10991094515395304355;
match current_block { match current_block {
2973387206439775448 => { 2973387206439775448 => {
if 0 == import_backup(context, param1) { if 0 == import_backup(context, param1.as_ptr()) {
current_block = 3568988166330621280; current_block = 3568988166330621280;
} else { } else {
current_block = 1118134448028020070; current_block = 1118134448028020070;
} }
} }
11250025114629486028 => { 11250025114629486028 => {
if 0 == import_self_keys(context, param1) { if 0 == import_self_keys(context, param1.as_ptr()) {
current_block = 3568988166330621280; current_block = 3568988166330621280;
} else { } else {
current_block = 1118134448028020070; current_block = 1118134448028020070;
} }
} }
12669919903773909120 => { 12669919903773909120 => {
if 0 == export_backup(context, param1) { if 0 == export_backup(context, param1.as_ptr()) {
current_block = 3568988166330621280; current_block = 3568988166330621280;
} else { } else {
current_block = 1118134448028020070; current_block = 1118134448028020070;
} }
} }
_ => { _ => {
if 0 == export_self_keys(context, param1) { if 0 == export_self_keys(context, param1.as_ptr()) {
current_block = 3568988166330621280; current_block = 3568988166330621280;
} else { } else {
current_block = 1118134448028020070; 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; current_block = 11250025114629486028;
match current_block { match current_block {
2973387206439775448 => { 2973387206439775448 => {
if 0 == import_backup(context, param1) { if 0 == import_backup(context, param1.as_ptr()) {
current_block = 3568988166330621280; current_block = 3568988166330621280;
} else { } else {
current_block = 1118134448028020070; current_block = 1118134448028020070;
} }
} }
11250025114629486028 => { 11250025114629486028 => {
if 0 == import_self_keys(context, param1) { if 0 == import_self_keys(context, param1.as_ptr()) {
current_block = 3568988166330621280; current_block = 3568988166330621280;
} else { } else {
current_block = 1118134448028020070; current_block = 1118134448028020070;
} }
} }
12669919903773909120 => { 12669919903773909120 => {
if 0 == export_backup(context, param1) { if 0 == export_backup(context, param1.as_ptr()) {
current_block = 3568988166330621280; current_block = 3568988166330621280;
} else { } else {
current_block = 1118134448028020070; current_block = 1118134448028020070;
} }
} }
_ => { _ => {
if 0 == export_self_keys(context, param1) { if 0 == export_self_keys(context, param1.as_ptr()) {
current_block = 3568988166330621280; current_block = 3568988166330621280;
} else { } else {
current_block = 1118134448028020070; 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; current_block = 12669919903773909120;
match current_block { match current_block {
2973387206439775448 => { 2973387206439775448 => {
if 0 == import_backup(context, param1) { if 0 == import_backup(context, param1.as_ptr()) {
current_block = 3568988166330621280; current_block = 3568988166330621280;
} else { } else {
current_block = 1118134448028020070; current_block = 1118134448028020070;
} }
} }
11250025114629486028 => { 11250025114629486028 => {
if 0 == import_self_keys(context, param1) { if 0 == import_self_keys(context, param1.as_ptr()) {
current_block = 3568988166330621280; current_block = 3568988166330621280;
} else { } else {
current_block = 1118134448028020070; current_block = 1118134448028020070;
} }
} }
12669919903773909120 => { 12669919903773909120 => {
if 0 == export_backup(context, param1) { if 0 == export_backup(context, param1.as_ptr()) {
current_block = 3568988166330621280; current_block = 3568988166330621280;
} else { } else {
current_block = 1118134448028020070; current_block = 1118134448028020070;
} }
} }
_ => { _ => {
if 0 == export_self_keys(context, param1) { if 0 == export_self_keys(context, param1.as_ptr()) {
current_block = 3568988166330621280; current_block = 3568988166330621280;
} else { } else {
current_block = 1118134448028020070; 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; current_block = 2973387206439775448;
match current_block { match current_block {
2973387206439775448 => { 2973387206439775448 => {
if 0 == import_backup(context, param1) { if 0 == import_backup(context, param1.as_ptr()) {
current_block = 3568988166330621280; current_block = 3568988166330621280;
} else { } else {
current_block = 1118134448028020070; current_block = 1118134448028020070;
} }
} }
11250025114629486028 => { 11250025114629486028 => {
if 0 == import_self_keys(context, param1) { if 0 == import_self_keys(context, param1.as_ptr()) {
current_block = 3568988166330621280; current_block = 3568988166330621280;
} else { } else {
current_block = 1118134448028020070; current_block = 1118134448028020070;
} }
} }
12669919903773909120 => { 12669919903773909120 => {
if 0 == export_backup(context, param1) { if 0 == export_backup(context, param1.as_ptr()) {
current_block = 3568988166330621280; current_block = 3568988166330621280;
} else { } else {
current_block = 1118134448028020070; current_block = 1118134448028020070;
} }
} }
_ => { _ => {
if 0 == export_self_keys(context, param1) { if 0 == export_self_keys(context, param1.as_ptr()) {
current_block = 3568988166330621280; current_block = 3568988166330621280;
} else { } else {
current_block = 1118134448028020070; 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 { if 0 != ongoing_allocated_here {
dc_free_ongoing(context); 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) let res = chrono::NaiveDateTime::from_timestamp(now as i64, 0)
.format("delta-chat-%Y-%m-%d.bak") .format("delta-chat-%Y-%m-%d.bak")
.to_string(); .to_string();
let buffer = to_cstring(res); let buffer = CString::yolo(res);
let dest_pathNfilename = dc_get_fine_pathNfilename(context, dir, buffer); let dest_pathNfilename = dc_get_fine_pathNfilename(context, dir, buffer.as_ptr());
free(buffer as *mut _);
if dest_pathNfilename.is_null() { if dest_pathNfilename.is_null() {
error!(context, 0, "Cannot get backup file name.",); 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 imported_cnt: libc::c_int = 0;
let mut suffix: *mut libc::c_char = 0 as *mut libc::c_char; 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 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 set_default: libc::c_int;
let mut buf: *mut libc::c_char = 0 as *mut libc::c_char; let mut buf: *mut libc::c_char = 0 as *mut libc::c_char;
let mut buf_bytes: size_t = 0 as size_t; 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(); let entry = entry.unwrap();
free(suffix as *mut libc::c_void); free(suffix as *mut libc::c_void);
let name_f = entry.file_name(); let name_f = entry.file_name();
free(name_c as *mut libc::c_void); let name_c = name_f.to_c_string().unwrap();
name_c = to_cstring(name_f.to_string_lossy()); suffix = dc_get_filesuffix_lc(name_c.as_ptr());
suffix = dc_get_filesuffix_lc(name_c);
if suffix.is_null() if suffix.is_null()
|| strcmp(suffix, b"asc\x00" as *const u8 as *const libc::c_char) != 0 || 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( path_plus_name = dc_mprintf(
b"%s/%s\x00" as *const u8 as *const libc::c_char, b"%s/%s\x00" as *const u8 as *const libc::c_char,
dir_name, dir_name,
name_c, name_c.as_ptr(),
); );
info!(context, 0, "Checking: {}", as_str(path_plus_name)); info!(context, 0, "Checking: {}", as_str(path_plus_name));
free(buf as *mut libc::c_void); 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; 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!( info!(
context, context,
0, 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(suffix as *mut libc::c_void);
free(path_plus_name as *mut libc::c_void); free(path_plus_name as *mut libc::c_void);
free(buf as *mut libc::c_void); free(buf as *mut libc::c_void);

View File

@@ -314,7 +314,7 @@ unsafe fn dc_job_do_DC_JOB_SEND(context: &Context, job: &mut dc_job_t) {
} }
match current_block { match current_block {
13109137661213826276 => { 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 { if strlen(filename) == 0 {
warn!(context, 0, "Missing file name for job {}", job.job_id,); warn!(context, 0, "Missing file name for job {}", job.job_id,);
} else if !(0 == dc_read_file(context, filename, &mut buf, &mut buf_bytes)) { } 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 { } else {
// no redo, no IMAP. moreover, as the data does not exist, there is no need in calling dc_set_msg_failed() // 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) { if msgtype_has_file((*mimefactory.msg).type_0) {
let pathNfilename = to_cstring( let pathNfilename = (*mimefactory.msg)
(*mimefactory.msg)
.param .param
.get(Param::File) .get(Param::File)
.unwrap_or_default(), .unwrap_or_default()
); .strdup();
if strlen(pathNfilename) > 0 { if strlen(pathNfilename) > 0 {
if ((*mimefactory.msg).type_0 == Viewtype::Image if ((*mimefactory.msg).type_0 == Viewtype::Image
|| (*mimefactory.msg).type_0 == Viewtype::Gif) || (*mimefactory.msg).type_0 == Viewtype::Gif)

View File

@@ -100,12 +100,9 @@ pub unsafe fn dc_send_locations_to_chat(
{ {
if 0 != seconds && !is_sending_locations_before { if 0 != seconds && !is_sending_locations_before {
msg = dc_msg_new(context, Viewtype::Text); msg = dc_msg_new(context, Viewtype::Text);
(*msg).text = to_cstring(context.stock_system_msg( (*msg).text = context
StockMessage::MsgLocationEnabled, .stock_system_msg(StockMessage::MsgLocationEnabled, "", "", 0)
"", .strdup();
"",
0,
));
(*msg).param.set_int(Param::Cmd, 8); (*msg).param.set_int(Param::Cmd, 8);
dc_send_msg(context, chat_id, msg); dc_send_msg(context, chat_id, msg);
} else if 0 == seconds && is_sending_locations_before { } else if 0 == seconds && is_sending_locations_before {
@@ -351,7 +348,7 @@ pub fn dc_get_location_kml(
} }
if 0 != success { if 0 != success {
unsafe { to_cstring(ret) } unsafe { ret.strdup() }
} else { } else {
std::ptr::null_mut() 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) let res = chrono::NaiveDateTime::from_timestamp(utc, 0)
.format("%Y-%m-%dT%H:%M:%SZ") .format("%Y-%m-%dT%H:%M:%SZ")
.to_string(); .to_string();
to_cstring(res) res.strdup()
} }
pub unsafe fn dc_get_message_kml( pub unsafe fn dc_get_message_kml(

View File

@@ -134,14 +134,14 @@ pub unsafe fn dc_lot_fill(
return; return;
} }
if (*msg).state == 19i32 { 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 (*lot).text1_meaning = 1i32
} else if (*msg).from_id == 1i32 as libc::c_uint { } else if (*msg).from_id == 1i32 as libc::c_uint {
if 0 != dc_msg_is_info(msg) || 0 != dc_chat_is_self_talk(chat) { if 0 != dc_msg_is_info(msg) || 0 != dc_chat_is_self_talk(chat) {
(*lot).text1 = 0 as *mut libc::c_char; (*lot).text1 = 0 as *mut libc::c_char;
(*lot).text1_meaning = 0i32 (*lot).text1_meaning = 0i32
} else { } else {
(*lot).text1 = to_cstring(context.stock_str(StockMessage::SelfMsg)); (*lot).text1 = context.stock_str(StockMessage::SelfMsg).strdup();
(*lot).text1_meaning = 3i32 (*lot).text1_meaning = 3i32
} }
} else if chat.is_null() { } else if chat.is_null() {

View File

@@ -158,13 +158,13 @@ pub unsafe fn dc_mimefactory_load_msg(
|rows| { |rows| {
for row in rows { for row in rows {
let (authname, addr) = row?; 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 { if clist_search_string_nocase((*factory).recipients_addr, addr_c) == 0 {
clist_insert_after( clist_insert_after(
(*factory).recipients_names, (*factory).recipients_names,
(*(*factory).recipients_names).last, (*(*factory).recipients_names).last,
if !authname.is_empty() { if !authname.is_empty() {
to_cstring(authname) authname.strdup()
} else { } else {
std::ptr::null_mut() std::ptr::null_mut()
} as *mut libc::c_void, } as *mut libc::c_void,
@@ -188,7 +188,7 @@ pub unsafe fn dc_mimefactory_load_msg(
if command == 5 { if command == 5 {
let email_to_remove = (*(*factory).msg).param.get(Param::Arg).unwrap_or_default(); 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 let self_addr = context
.sql .sql
@@ -234,8 +234,8 @@ pub unsafe fn dc_mimefactory_load_msg(
); );
match row { match row {
Ok((in_reply_to, references)) => { Ok((in_reply_to, references)) => {
(*factory).in_reply_to = to_cstring(in_reply_to); (*factory).in_reply_to = in_reply_to.strdup();
(*factory).references = to_cstring(references); (*factory).references = references.strdup();
} }
Err(err) => { Err(err) => {
error!( error!(
@@ -259,27 +259,28 @@ pub unsafe fn dc_mimefactory_load_msg(
unsafe fn load_from(mut factory: *mut dc_mimefactory_t) { unsafe fn load_from(mut factory: *mut dc_mimefactory_t) {
let context = (*factory).context; let context = (*factory).context;
(*factory).from_addr = to_cstring( (*factory).from_addr = context
context
.sql .sql
.get_config(context, "configured_addr") .get_config(context, "configured_addr")
.unwrap_or_default(), .unwrap_or_default()
); .strdup();
(*factory).from_displayname = to_cstring( (*factory).from_displayname = context
context
.sql .sql
.get_config(context, "displayname") .get_config(context, "displayname")
.unwrap_or_default(), .unwrap_or_default()
); .strdup();
(*factory).selfstatus = to_cstring(
context (*factory).selfstatus = context
.sql .sql
.get_config(context, "selfstatus") .get_config(context, "selfstatus")
.unwrap_or_default(), .unwrap_or_default()
); .strdup();
if (*factory).selfstatus.is_null() { 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 { if command == 5 {
let email_to_remove = let email_to_remove = (*msg).param.get(Param::Arg).unwrap_or_default().strdup();
to_cstring((*msg).param.get(Param::Arg).unwrap_or_default());
if strlen(email_to_remove) > 0 { if strlen(email_to_remove) > 0 {
mailimf_fields_add( mailimf_fields_add(
imf_fields, imf_fields,
@@ -589,7 +589,7 @@ pub unsafe fn dc_mimefactory_render(mut factory: *mut dc_mimefactory_t) -> libc:
} }
} else if command == 4 { } else if command == 4 {
do_gossip = 1; 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 { if strlen(email_to_add) > 0 {
mailimf_fields_add( mailimf_fields_add(
imf_fields, imf_fields,
@@ -619,7 +619,7 @@ pub unsafe fn dc_mimefactory_render(mut factory: *mut dc_mimefactory_t) -> libc:
); );
} }
} else if command == 2 { } 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( mailimf_fields_add(
imf_fields, imf_fields,
mailimf_field_new_custom( 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), strdup(b"v1\x00" as *const u8 as *const libc::c_char),
), ),
); );
placeholdertext = placeholdertext = (*factory)
to_cstring((*factory).context.stock_str(StockMessage::AcSetupMsgBody)); .context
.stock_str(StockMessage::AcSetupMsgBody)
.strdup();
} }
if command == 7 { 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 { if strlen(step) > 0 {
info!( info!(
(*msg).context, (*msg).context,
@@ -680,7 +682,7 @@ pub unsafe fn dc_mimefactory_render(mut factory: *mut dc_mimefactory_t) -> libc:
step, 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 { if strlen(param2) > 0 {
mailimf_fields_add( mailimf_fields_add(
imf_fields, 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 { if strlen(fingerprint) > 0 {
mailimf_fields_add( mailimf_fields_add(
imf_fields, 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) { let grpid = match (*msg).param.get(Param::Arg4) {
Some(id) => to_cstring(id), Some(id) => id.strdup(),
None => std::ptr::null_mut(), None => std::ptr::null_mut(),
}; };
if !grpid.is_null() { 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, ) as *mut libc::c_void,
); );
mailmime_add_part(message, multipart); mailmime_add_part(message, multipart);
let p1: *mut libc::c_char; let p1 = if 0
let p2: *mut libc::c_char; != (*(*factory).msg)
if 0 != (*(*factory).msg)
.param .param
.get_int(Param::GuranteeE2ee) .get_int(Param::GuranteeE2ee)
.unwrap_or_default() .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) (*factory)
.context .context
.stock_string_repl_str(StockMessage::ReadRcptMailBody, as_str(p1)), .stock_str(StockMessage::EncryptedMsg)
); .into_owned()
message_text = dc_mprintf(b"%s\r\n\x00" as *const u8 as *const libc::c_char, p2); } else {
free(p1 as *mut libc::c_void); to_string(dc_msg_get_summarytext((*factory).msg, 32))
free(p2 as *mut libc::c_void); };
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); let human_mime_part: *mut mailmime = build_body_text(message_text);
mailmime_add_part(multipart, human_mime_part); mailmime_add_part(multipart, human_mime_part);
message_text2 = message_text2 =
@@ -1102,7 +1102,7 @@ unsafe fn get_subject(
b"\x00" as *const u8 as *const libc::c_char b"\x00" as *const u8 as *const libc::c_char
}; };
if (*msg).param.get_int(Param::Cmd).unwrap_or_default() == 6 { 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 } 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 || (*chat).type_0 == DC_CHAT_TYPE_VERIFIED_GROUP as libc::c_int
{ {
@@ -1165,12 +1165,12 @@ unsafe fn build_body_file(
let pathNfilename = (*msg) let pathNfilename = (*msg)
.param .param
.get(Param::File) .get(Param::File)
.map(|s| to_cstring(s)) .map(|s| s.strdup())
.unwrap_or_else(|| std::ptr::null_mut()); .unwrap_or_else(|| std::ptr::null_mut());
let mut mimetype = (*msg) let mut mimetype = (*msg)
.param .param
.get(Param::MimeType) .get(Param::MimeType)
.map(|s| to_cstring(s)) .map(|s| s.strdup())
.unwrap_or_else(|| std::ptr::null_mut()); .unwrap_or_else(|| std::ptr::null_mut());
let suffix = dc_get_filesuffix_lc(pathNfilename); let suffix = dc_get_filesuffix_lc(pathNfilename);
@@ -1189,7 +1189,7 @@ unsafe fn build_body_file(
let res = ts let res = ts
.format(&format!("voice-message_%Y-%m-%d_%H-%M-%S.{}", suffix)) .format(&format!("voice-message_%Y-%m-%d_%H-%M-%S.{}", suffix))
.to_string(); .to_string();
filename_to_send = to_cstring(res); filename_to_send = res.strdup();
} else if (*msg).type_0 == Viewtype::Audio { } else if (*msg).type_0 == Viewtype::Audio {
filename_to_send = dc_get_filename(pathNfilename) filename_to_send = dc_get_filename(pathNfilename)
} else if (*msg).type_0 == Viewtype::Image || (*msg).type_0 == Viewtype::Gif { } 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)] #[allow(non_snake_case)]
unsafe fn is_file_size_okay(msg: *const dc_msg_t) -> bool { unsafe fn is_file_size_okay(msg: *const dc_msg_t) -> bool {
let mut file_size_okay = true; 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); let bytes = dc_get_filebytes((*msg).context, pathNfilename);
if bytes > (49 * 1024 * 1024 / 4 * 3) { if bytes > (49 * 1024 * 1024 / 4 * 3) {

View File

@@ -1312,9 +1312,8 @@ unsafe fn dc_mimeparser_add_single_part_if_known(
} }
if !filename_parts.is_empty() { if !filename_parts.is_empty() {
free(desired_filename as *mut libc::c_void); free(desired_filename as *mut libc::c_void);
let parts_c = to_cstring(filename_parts); let parts_c = CString::yolo(filename_parts);
desired_filename = dc_decode_ext_header(parts_c); desired_filename = dc_decode_ext_header(parts_c.as_ptr());
free(parts_c as *mut _);
} }
if desired_filename.is_null() { if desired_filename.is_null() {
let param = mailmime_find_ct_parameter( let param = mailmime_find_ct_parameter(

View File

@@ -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); ret += &format!("Cannot load message #{}.", msg_id as usize);
dc_msg_unref(msg); dc_msg_unref(msg);
dc_contact_unref(contact_from); dc_contact_unref(contact_from);
return to_cstring(ret); return ret.strdup();
} }
let rawtxt = rawtxt.unwrap(); let rawtxt = rawtxt.unwrap();
let rawtxt = dc_truncate_str(rawtxt.trim(), 100000); 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 // device-internal message, no further details needed
dc_msg_unref(msg); dc_msg_unref(msg);
dc_contact_unref(contact_from); dc_contact_unref(contact_from);
return to_cstring(ret); return ret.strdup();
} }
context 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_msg_unref(msg);
dc_contact_unref(contact_from); 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> { 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) { if !(msg.is_null() || (*msg).magic != 0x11561156i32 as libc::c_uint) {
match (*msg).param.get(Param::MimeType) { match (*msg).param.get(Param::MimeType) {
Some(m) => { Some(m) => {
ret = to_cstring(m); ret = m.strdup();
} }
None => { None => {
if let Some(file) = (*msg).param.get(Param::File) { if let Some(file) = (*msg).param.get(Param::File) {
let file_c = to_cstring(file); let file_c = CString::yolo(file);
dc_msg_guess_msgtype_from_suffix(file_c, 0 as *mut Viewtype, &mut ret); dc_msg_guess_msgtype_from_suffix(file_c.as_ptr(), 0 as *mut Viewtype, &mut ret);
if ret.is_null() { if ret.is_null() {
ret = dc_strdup( ret = dc_strdup(
b"application/octet-stream\x00" as *const u8 as *const libc::c_char, 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 !(msg.is_null() || (*msg).magic != 0x11561156i32 as libc::c_uint) {
if let Some(file_rel) = (*msg).param.get(Param::File) { if let Some(file_rel) = (*msg).param.get(Param::File) {
let file_rel_c = to_cstring(file_rel); let file_rel_c = CString::yolo(file_rel);
file_abs = dc_get_abs_path((*msg).context, file_rel_c); file_abs = dc_get_abs_path((*msg).context, file_rel_c.as_ptr());
free(file_rel_c as *mut _);
} }
} }
if !file_abs.is_null() { 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); dc_msg_empty(msg);
(*msg).id = row.get::<_, i32>(0)? as u32; (*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<String>>(2)? { (*msg).in_reply_to = match row.get::<_, Option<String>>(2)? {
Some(s) => to_cstring(s), Some(s) => s.strdup(),
None => std::ptr::null_mut(), 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).server_uid = row.get(4)?;
(*msg).move_state = row.get(5)?; (*msg).move_state = row.get(5)?;
(*msg).chat_id = row.get(6)?; (*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).type_0 = row.get(12)?;
(*msg).state = row.get(13)?; (*msg).state = row.get(13)?;
(*msg).is_dc_message = row.get(14)?; (*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).param = row.get::<_, String>(16)?.parse().unwrap_or_default();
(*msg).starred = row.get(17)?; (*msg).starred = row.get(17)?;
(*msg).hidden = row.get(18)?; (*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 { if let Some(headers) = headers {
let h = to_cstring(headers); let h = CString::yolo(headers);
let res = dc_strdup_keep_null(h); dc_strdup_keep_null(h.as_ptr())
free(h as *mut _);
res
} else { } else {
std::ptr::null_mut() 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); let res = dc_truncate_str(as_str((*msg).text), 30000);
to_cstring(res) res.strdup()
} }
#[allow(non_snake_case)] #[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 !(msg.is_null() || (*msg).magic != 0x11561156i32 as libc::c_uint) {
if let Some(file) = (*msg).param.get(Param::File) { if let Some(file) = (*msg).param.get(Param::File) {
let file_c = to_cstring(file); let file_c = CString::yolo(file);
ret = dc_get_filename(file_c); ret = dc_get_filename(file_c.as_ptr());
free(file_c as *mut _);
} }
} }
if !ret.is_null() { 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 !(msg.is_null() || (*msg).magic != 0x11561156i32 as libc::c_uint) {
if let Some(file) = (*msg).param.get(Param::File) { if let Some(file) = (*msg).param.get(Param::File) {
let file_c = to_cstring(file); let file_c = CString::yolo(file);
ret = dc_get_filebytes((*msg).context, file_c); ret = dc_get_filebytes((*msg).context, file_c.as_ptr());
free(file_c as *mut _);
} }
} }
@@ -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 value: *mut libc::c_char = 0 as *mut libc::c_char;
let mut append_text: libc::c_int = 1i32; let mut append_text: libc::c_int = 1i32;
match type_0 { match type_0 {
Viewtype::Image => prefix = to_cstring(context.stock_str(StockMessage::Image)), Viewtype::Image => prefix = context.stock_str(StockMessage::Image).strdup(),
Viewtype::Gif => prefix = to_cstring(context.stock_str(StockMessage::Gif)), Viewtype::Gif => prefix = context.stock_str(StockMessage::Gif).strdup(),
Viewtype::Video => prefix = to_cstring(context.stock_str(StockMessage::Video)), Viewtype::Video => prefix = context.stock_str(StockMessage::Video).strdup(),
Viewtype::Voice => prefix = to_cstring(context.stock_str(StockMessage::VoiceMessage)), Viewtype::Voice => prefix = context.stock_str(StockMessage::VoiceMessage).strdup(),
Viewtype::Audio | Viewtype::File => { Viewtype::Audio | Viewtype::File => {
if param.get_int(Param::Cmd) == Some(6) { 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 append_text = 0i32
} else { } 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); value = dc_get_filename(pathNfilename);
let label = CString::new( let label = CString::new(
context context
@@ -888,7 +885,7 @@ pub unsafe fn dc_msg_get_summarytext_by_raw(
} }
_ => { _ => {
if param.get_int(Param::Cmd) == Some(9) { 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; append_text = 0;
} }
} }
@@ -1387,7 +1384,7 @@ pub fn dc_rfc724_mid_exists(
&[as_str(rfc724_mid)], &[as_str(rfc724_mid)],
|row| { |row| {
if !ret_server_folder.is_null() { 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() { if !ret_server_uid.is_null() {
unsafe { *ret_server_uid = row.get(1)? }; unsafe { *ret_server_uid = row.get(1)? };

View File

@@ -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"); let param: Params = as_str(fragment).parse().expect("invalid params");
addr = param addr = param
.get(Param::Forwarded) .get(Param::Forwarded)
.map(|s| to_cstring(s)) .map(|s| s.strdup())
.unwrap_or_else(|| std::ptr::null_mut()); .unwrap_or_else(|| std::ptr::null_mut());
if !addr.is_null() { if !addr.is_null() {
if let Some(ref name_enc) = param.get(Param::SetLongitude) { if let Some(ref name_enc) = param.get(Param::SetLongitude) {
let name_r = percent_decode_str(name_enc) let name_r = percent_decode_str(name_enc)
.decode_utf8() .decode_utf8()
.expect("invalid name"); .expect("invalid name");
name = to_cstring(name_r); name = name_r.strdup();
dc_normalize_name(name); dc_normalize_name(name);
} }
invitenumber = param invitenumber = param
.get(Param::ProfileImage) .get(Param::ProfileImage)
.map(|s| to_cstring(s)) .map(|s| s.strdup())
.unwrap_or_else(|| std::ptr::null_mut()); .unwrap_or_else(|| std::ptr::null_mut());
auth = param auth = param
.get(Param::Auth) .get(Param::Auth)
.map(|s| to_cstring(s)) .map(|s| s.strdup())
.unwrap_or_else(|| std::ptr::null_mut()); .unwrap_or_else(|| std::ptr::null_mut());
grpid = param grpid = param
.get(Param::GroupId) .get(Param::GroupId)
.map(|s| to_cstring(s)) .map(|s| s.strdup())
.unwrap_or_else(|| std::ptr::null_mut()); .unwrap_or_else(|| std::ptr::null_mut());
if !grpid.is_null() { if !grpid.is_null() {
if let Some(grpname_enc) = param.get(Param::GroupName) { if let Some(grpname_enc) = param.get(Param::GroupName) {
let grpname_r = percent_decode_str(grpname_enc) let grpname_r = percent_decode_str(grpname_enc)
.decode_utf8() .decode_utf8()
.expect("invalid groupname"); .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 { if let Some(peerstate) = peerstate {
(*qr_parsed).state = 210i32; (*qr_parsed).state = 210i32;
let addr_ptr = if let Some(ref addr) = peerstate.addr { let addr_ptr = if let Some(ref addr) = peerstate.addr {
to_cstring(addr) addr.strdup()
} else { } else {
std::ptr::null() std::ptr::null()
}; };

View File

@@ -1210,7 +1210,7 @@ unsafe fn create_or_lookup_group(
grpimage = (*part) grpimage = (*part)
.param .param
.get(Param::File) .get(Param::File)
.map(|s| to_cstring(s)) .map(|s| s.strdup())
.unwrap_or_else(|| std::ptr::null_mut()); .unwrap_or_else(|| std::ptr::null_mut());
ok = 1 ok = 1
} }
@@ -1407,10 +1407,12 @@ unsafe fn create_or_lookup_adhoc_group(
{ {
grpname = dc_strdup(mime_parser.subject) grpname = dc_strdup(mime_parser.subject)
} else { } else {
grpname = to_cstring(context.stock_string_repl_int( grpname = context
.stock_string_repl_int(
StockMessage::Member, StockMessage::Member,
dc_array_get_cnt(member_ids) as libc::c_int, dc_array_get_cnt(member_ids) as libc::c_int,
)); )
.strdup();
} }
chat_id = chat_id =
create_group_record(context, grpid, grpname, create_blocked, 0); create_group_record(context, grpid, grpname, create_blocked, 0);
@@ -1519,7 +1521,7 @@ fn hex_hash(s: impl AsRef<str>) -> *const libc::c_char {
let bytes = s.as_ref().as_bytes(); let bytes = s.as_ref().as_bytes();
let result = Sha256::digest(bytes); let result = Sha256::digest(bytes);
let result_hex = hex::encode(&result[..8]); let result_hex = hex::encode(&result[..8]);
unsafe { to_cstring(result_hex) as *const _ } unsafe { result_hex.strdup() as *const _ }
} }
#[allow(non_snake_case)] #[allow(non_snake_case)]
@@ -1604,7 +1606,7 @@ unsafe fn check_verified_properties(
let contact = dc_contact_new(context); let contact = dc_contact_new(context);
let verify_fail = |reason: String| { 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); warn!(context, 0, "{}", reason);
}; };
@@ -1714,7 +1716,7 @@ unsafe fn set_better_msg<T: AsRef<str>>(mime_parser: &dc_mimeparser_t, better_ms
carray_get(mime_parser.parts, 0 as libc::c_uint) as *mut dc_mimepart_t; carray_get(mime_parser.parts, 0 as libc::c_uint) as *mut dc_mimepart_t;
if (*part).type_0 == 10 { if (*part).type_0 == 10 {
free((*part).msg as *mut libc::c_void); free((*part).msg as *mut libc::c_void);
(*part).msg = to_cstring(msg); (*part).msg = msg.strdup();
} }
}; };
} }

View File

@@ -40,7 +40,7 @@ pub unsafe fn dc_get_securejoin_qr(
let mut chat = 0 as *mut Chat; let mut chat = 0 as *mut Chat;
let mut group_name = 0 as *mut libc::c_char; let mut group_name = 0 as *mut libc::c_char;
let mut group_name_urlencoded = 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<String> = None;
dc_ensure_secret_key_exists(context); dc_ensure_secret_key_exists(context);
invitenumber = dc_token_lookup(context, DC_TOKEN_INVITENUMBER, group_chat_id); 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); free(group_name_urlencoded as *mut libc::c_void);
if let Some(qr) = qr { if let Some(qr) = qr {
to_cstring(qr) qr.strdup()
} else { } else {
std::ptr::null_mut() std::ptr::null_mut()
} }

View File

@@ -229,7 +229,7 @@ impl dc_simplify_t {
} }
dc_free_splitted_lines(lines); dc_free_splitted_lines(lines);
to_cstring(ret) ret.strdup()
} }
} }

View File

@@ -1,4 +1,4 @@
use std::ffi::CStr; use std::ffi::{CStr, CString};
use charset::Charset; use charset::Charset;
use mmime::mailmime_decode::*; 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()); assert!(!cur.is_null());
let bytes = std::slice::from_raw_parts(cur as *const _, strlen(cur)); let bytes = std::slice::from_raw_parts(cur as *const _, strlen(cur));
let raw = to_cstring(format!("={}", &hex::encode_upper(bytes)[..2])); let raw = CString::yolo(format!("={}", &hex::encode_upper(bytes)[..2]));
libc::memcpy(target as *mut _, raw as *const _, 4); libc::memcpy(target as *mut _, raw.as_ptr() as *const _, 4);
free(raw as *mut libc::c_void);
} }
#[cfg(test)] #[cfg(test)]

View File

@@ -42,7 +42,7 @@ pub fn dc_token_lookup(
params![namespc as i32, foreign_id as i32], params![namespc as i32, foreign_id as i32],
0, 0,
) )
.map(|s| unsafe { to_cstring(s) }) .map(|s| unsafe { s.strdup() })
.unwrap_or_else(|| std::ptr::null_mut()) .unwrap_or_else(|| std::ptr::null_mut())
} }

View File

@@ -178,14 +178,13 @@ pub unsafe fn dc_trim(buf: *mut libc::c_char) {
/* the result must be free()'d */ /* the result must be free()'d */
pub unsafe fn dc_strlower(in_0: *const libc::c_char) -> *mut libc::c_char { 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) { pub unsafe fn dc_strlower_in_place(in_0: *mut libc::c_char) {
let raw = to_cstring(to_string(in_0).to_lowercase()); let raw = CString::yolo(to_string(in_0).to_lowercase());
assert_eq!(strlen(in_0), strlen(raw)); assert_eq!(strlen(in_0), strlen(raw.as_ptr()));
memcpy(in_0 as *mut _, raw as *const _, strlen(in_0)); memcpy(in_0 as *mut _, raw.as_ptr() as *const _, strlen(in_0));
free(raw as *mut _);
} }
pub unsafe fn dc_str_contains( 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 buf = std::slice::from_raw_parts(buf, bytes);
let raw = hex::encode_upper(buf); let raw = hex::encode_upper(buf);
to_cstring(raw) raw.strdup()
} }
/* remove all \r characters from string */ /* 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( pub unsafe fn dc_str_to_clist(
@@ -1236,10 +1235,8 @@ pub unsafe fn dc_write_file(
#[allow(non_snake_case)] #[allow(non_snake_case)]
pub fn dc_write_file_safe(context: &Context, pathNfilename: impl AsRef<str>, buf: &[u8]) -> bool { pub fn dc_write_file_safe(context: &Context, pathNfilename: impl AsRef<str>, buf: &[u8]) -> bool {
let pathNfilename_abs = unsafe { let pathNfilename_abs = unsafe {
let n = to_cstring(pathNfilename.as_ref()); let n = CString::yolo(pathNfilename.as_ref());
let res = dc_get_abs_path(context, n); dc_get_abs_path(context, n.as_ptr())
free(n as *mut _);
res
}; };
if pathNfilename_abs.is_null() { if pathNfilename_abs.is_null() {
return false; return false;
@@ -1287,10 +1284,8 @@ pub unsafe fn dc_read_file(
#[allow(non_snake_case)] #[allow(non_snake_case)]
pub fn dc_read_file_safe(context: &Context, pathNfilename: impl AsRef<str>) -> Option<Vec<u8>> { pub fn dc_read_file_safe(context: &Context, pathNfilename: impl AsRef<str>) -> Option<Vec<u8>> {
let pathNfilename_abs = unsafe { let pathNfilename_abs = unsafe {
let n = to_cstring(pathNfilename.as_ref()); let n = CString::yolo(pathNfilename.as_ref());
let p = dc_get_abs_path(context, n); dc_get_abs_path(context, n.as_ptr())
free(n as *mut _);
p
}; };
if pathNfilename_abs.is_null() { 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: Into<Vec<u8>>>(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<T: AsRef<str>> 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! /// Needs to free the result after use!
pub unsafe fn to_cstring<S: AsRef<str>>(s: S) -> *mut libc::c_char { pub unsafe fn to_cstring<S: AsRef<str>>(s: S) -> *mut libc::c_char {
let cstr = CString::new(s.as_ref()).expect("invalid string converted"); let cstr = CString::new(s.as_ref()).expect("invalid string converted");
@@ -2085,4 +2125,29 @@ mod tests {
let ptr = some_path.as_ptr(); let ptr = some_path.as_ptr();
assert_eq!(as_path_unicode(ptr), std::ffi::OsString::from("/some/path")); 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);
}
}
} }

View File

@@ -1,3 +1,4 @@
use std::ffi::CString;
use std::net; use std::net;
use std::sync::{Arc, Condvar, Mutex, RwLock}; use std::sync::{Arc, Condvar, Mutex, RwLock};
use std::time::{Duration, SystemTime}; use std::time::{Duration, SystemTime};
@@ -5,10 +6,9 @@ use std::time::{Duration, SystemTime};
use crate::constants::*; use crate::constants::*;
use crate::context::Context; use crate::context::Context;
use crate::dc_loginparam::*; 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::oauth2::dc_get_oauth2_access_token;
use crate::types::*; use crate::types::*;
use crate::x::free;
pub const DC_IMAP_SEEN: usize = 0x0001; pub const DC_IMAP_SEEN: usize = 0x0001;
pub const DC_REGENERATE: usize = 0x01; pub const DC_REGENERATE: usize = 0x01;
@@ -843,10 +843,8 @@ impl Imap {
.expect("missing message id"); .expect("missing message id");
if 0 == unsafe { if 0 == unsafe {
let message_id_c = to_cstring(message_id); let message_id_c = CString::yolo(message_id);
let res = (self.precheck_imf)(context, message_id_c, folder.as_ref(), cur_uid); (self.precheck_imf)(context, message_id_c.as_ptr(), folder.as_ref(), cur_uid)
free(message_id_c as *mut _);
res
} { } {
// check passed, go fetch the rest // check passed, go fetch the rest
if self.fetch_single_msg(context, &folder, cur_uid) == 0 { if self.fetch_single_msg(context, &folder, cur_uid) == 0 {

View File

@@ -7,10 +7,9 @@ macro_rules! info {
#[allow(unused_unsafe)] #[allow(unused_unsafe)]
unsafe { unsafe {
let formatted = format!($msg, $($args),*); 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, $ctx.call_cb($crate::constants::Event::INFO, $data1 as libc::uintptr_t,
formatted_c as libc::uintptr_t); formatted_c.as_ptr() as libc::uintptr_t);
libc::free(formatted_c as *mut libc::c_void);
}}; }};
} }
@@ -23,10 +22,9 @@ macro_rules! warn {
#[allow(unused_unsafe)] #[allow(unused_unsafe)]
unsafe { unsafe {
let formatted = format!($msg, $($args),*); 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, $ctx.call_cb($crate::constants::Event::WARNING, $data1 as libc::uintptr_t,
formatted_c as libc::uintptr_t); formatted_c.as_ptr() as libc::uintptr_t);
libc::free(formatted_c as *mut libc::c_void) ;
}}; }};
} }
@@ -39,10 +37,9 @@ macro_rules! error {
#[allow(unused_unsafe)] #[allow(unused_unsafe)]
unsafe { unsafe {
let formatted = format!($msg, $($args),*); 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, $ctx.call_cb($crate::constants::Event::ERROR, $data1 as libc::uintptr_t,
formatted_c as libc::uintptr_t); formatted_c.as_ptr() as libc::uintptr_t);
libc::free(formatted_c as *mut libc::c_void);
}}; }};
} }
@@ -55,9 +52,8 @@ macro_rules! log_event {
#[allow(unused_unsafe)] #[allow(unused_unsafe)]
unsafe { unsafe {
let formatted = format!($msg, $($args),*); 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, $ctx.call_cb($event, $data1 as libc::uintptr_t,
formatted_c as libc::uintptr_t); formatted_c.as_ptr() as libc::uintptr_t);
libc::free(formatted_c as *mut libc::c_void);
}}; }};
} }

View File

@@ -462,13 +462,11 @@ mod tests {
use super::*; use super::*;
use pretty_assertions::assert_eq; use pretty_assertions::assert_eq;
use tempfile::{tempdir, TempDir}; use tempfile::TempDir;
use crate::context::*;
#[test] #[test]
fn test_peerstate_save_to_db() { 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 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(); 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, ctx: Context,
dir: TempDir, 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 }
}
} }

View File

@@ -10,7 +10,6 @@ use crate::dc_tools::*;
use crate::error::{Error, Result}; use crate::error::{Error, Result};
use crate::param::*; use crate::param::*;
use crate::peerstate::*; use crate::peerstate::*;
use crate::x::*;
const DC_OPEN_READONLY: usize = 0x01; const DC_OPEN_READONLY: usize = 0x01;
@@ -1049,9 +1048,8 @@ pub fn housekeeping(context: &Context) {
entry.file_name() entry.file_name()
); );
unsafe { unsafe {
let path = to_cstring(entry.path().to_str().unwrap()); let path = entry.path().to_c_string().unwrap();
dc_delete_file(context, path); dc_delete_file(context, path.as_ptr());
free(path as *mut _);
} }
} }
} }

View File

@@ -671,7 +671,7 @@ fn test_encryption_decryption() {
assert!(ctext.starts_with("-----BEGIN PGP MESSAGE-----")); assert!(ctext.starts_with("-----BEGIN PGP MESSAGE-----"));
let ctext_signed_bytes = ctext.len(); let ctext_signed_bytes = ctext.len();
let ctext_signed = to_cstring(ctext); let ctext_signed = CString::yolo(ctext);
let ctext = dc_pgp_pk_encrypt( let ctext = dc_pgp_pk_encrypt(
original_text as *const libc::c_void, original_text as *const libc::c_void,
@@ -684,7 +684,7 @@ fn test_encryption_decryption() {
assert!(ctext.starts_with("-----BEGIN PGP MESSAGE-----")); assert!(ctext.starts_with("-----BEGIN PGP MESSAGE-----"));
let ctext_unsigned_bytes = ctext.len(); let ctext_unsigned_bytes = ctext.len();
let ctext_unsigned = to_cstring(ctext); let ctext_unsigned = CString::yolo(ctext);
let mut keyring = Keyring::default(); let mut keyring = Keyring::default();
keyring.add_owned(private_key); keyring.add_owned(private_key);
@@ -698,7 +698,7 @@ fn test_encryption_decryption() {
let mut valid_signatures: HashSet<String> = Default::default(); let mut valid_signatures: HashSet<String> = Default::default();
let plain = dc_pgp_pk_decrypt( let plain = dc_pgp_pk_decrypt(
ctext_signed as *const _, ctext_signed.as_ptr() as *const _,
ctext_signed_bytes, ctext_signed_bytes,
&keyring, &keyring,
&public_keyring, &public_keyring,
@@ -713,7 +713,7 @@ fn test_encryption_decryption() {
let empty_keyring = Keyring::default(); let empty_keyring = Keyring::default();
let plain = dc_pgp_pk_decrypt( let plain = dc_pgp_pk_decrypt(
ctext_signed as *const _, ctext_signed.as_ptr() as *const _,
ctext_signed_bytes, ctext_signed_bytes,
&keyring, &keyring,
&empty_keyring, &empty_keyring,
@@ -726,7 +726,7 @@ fn test_encryption_decryption() {
valid_signatures.clear(); valid_signatures.clear();
let plain = dc_pgp_pk_decrypt( let plain = dc_pgp_pk_decrypt(
ctext_signed as *const _, ctext_signed.as_ptr() as *const _,
ctext_signed_bytes, ctext_signed_bytes,
&keyring, &keyring,
&public_keyring2, &public_keyring2,
@@ -741,7 +741,7 @@ fn test_encryption_decryption() {
public_keyring2.add_ref(&public_key); public_keyring2.add_ref(&public_key);
let plain = dc_pgp_pk_decrypt( let plain = dc_pgp_pk_decrypt(
ctext_signed as *const _, ctext_signed.as_ptr() as *const _,
ctext_signed_bytes, ctext_signed_bytes,
&keyring, &keyring,
&public_keyring2, &public_keyring2,
@@ -754,7 +754,7 @@ fn test_encryption_decryption() {
valid_signatures.clear(); valid_signatures.clear();
let plain = dc_pgp_pk_decrypt( let plain = dc_pgp_pk_decrypt(
ctext_unsigned as *const _, ctext_unsigned.as_ptr() as *const _,
ctext_unsigned_bytes, ctext_unsigned_bytes,
&keyring, &keyring,
&public_keyring, &public_keyring,
@@ -762,7 +762,6 @@ fn test_encryption_decryption() {
) )
.unwrap(); .unwrap();
free(ctext_unsigned as *mut _);
assert_eq!(std::str::from_utf8(&plain).unwrap(), as_str(original_text),); assert_eq!(std::str::from_utf8(&plain).unwrap(), as_str(original_text),);
valid_signatures.clear(); valid_signatures.clear();
@@ -773,7 +772,7 @@ fn test_encryption_decryption() {
public_keyring.add_ref(&public_key); public_keyring.add_ref(&public_key);
let plain = dc_pgp_pk_decrypt( let plain = dc_pgp_pk_decrypt(
ctext_signed as *const _, ctext_signed.as_ptr() as *const _,
ctext_signed_bytes, ctext_signed_bytes,
&keyring, &keyring,
&public_keyring, &public_keyring,
@@ -781,7 +780,6 @@ fn test_encryption_decryption() {
) )
.unwrap(); .unwrap();
free(ctext_signed as *mut _);
assert_eq!(std::str::from_utf8(&plain).unwrap(), as_str(original_text),); assert_eq!(std::str::from_utf8(&plain).unwrap(), as_str(original_text),);
} }
} }
@@ -808,7 +806,7 @@ unsafe fn create_test_context() -> TestContext {
assert!( assert!(
dc_open(&mut ctx, dbfile.to_str().unwrap(), None), dc_open(&mut ctx, dbfile.to_str().unwrap(), None),
"Failed to open {}", "Failed to open {}",
dbfile.to_str().unwrap() dbfile.display()
); );
TestContext { ctx: ctx, dir: dir } TestContext { ctx: ctx, dir: dir }
} }
@@ -931,29 +929,24 @@ fn test_stress_tests() {
fn test_get_contacts() { fn test_get_contacts() {
unsafe { unsafe {
let context = create_test_context(); let context = create_test_context();
let name = to_cstring("some2"); let name = CString::yolo("some2");
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), 0); assert_eq!(dc_array_get_cnt(contacts), 0);
dc_array_unref(contacts); dc_array_unref(contacts);
free(name as *mut _);
let name = to_cstring("bob"); let name = CString::yolo("bob");
let email = to_cstring("bob@mail.de"); let email = CString::yolo("bob@mail.de");
let id = dc_create_contact(&context.ctx, name, email); let id = dc_create_contact(&context.ctx, name.as_ptr(), email.as_ptr());
assert_ne!(id, 0); 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); assert_eq!(dc_array_get_cnt(contacts), 1);
dc_array_unref(contacts); dc_array_unref(contacts);
let name2 = to_cstring("alice"); let name2 = CString::yolo("alice");
let contacts = dc_get_contacts(&context.ctx, 0, name2); let contacts = dc_get_contacts(&context.ctx, 0, name2.as_ptr());
assert_eq!(dc_array_get_cnt(contacts), 0); assert_eq!(dc_array_get_cnt(contacts), 0);
dc_array_unref(contacts); 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() { fn test_chat() {
unsafe { unsafe {
let context = create_test_context(); let context = create_test_context();
let name = to_cstring("bob"); let name = CString::yolo("bob");
let email = to_cstring("bob@mail.de"); let email = CString::yolo("bob@mail.de");
let contact1 = dc_create_contact(&context.ctx, name, email); let contact1 = dc_create_contact(&context.ctx, name.as_ptr(), email.as_ptr());
free(name as *mut _);
free(email as *mut _);
assert_ne!(contact1, 0); assert_ne!(contact1, 0);
let chat_id = dc_create_chat_by_contact_id(&context.ctx, contact1); let chat_id = dc_create_chat_by_contact_id(&context.ctx, contact1);