audit use of to_cstring and fix ub

This commit is contained in:
dignifiedquire
2019-07-18 22:47:47 +02:00
committed by holger krekel
parent 618087e5a7
commit c68e7ae14e
26 changed files with 265 additions and 247 deletions

View File

@@ -111,7 +111,7 @@ pub unsafe extern "C" fn dc_get_config(
match config::Config::from_str(dc_tools::as_str(key)) { match config::Config::from_str(dc_tools::as_str(key)) {
Ok(key) => { Ok(key) => {
let value = context.get_config(key).unwrap_or_default(); let value = context.get_config(key).unwrap_or_default();
into_cstring(value) dc_tools::to_cstring(value)
} }
Err(_) => std::ptr::null_mut(), Err(_) => std::ptr::null_mut(),
} }
@@ -137,7 +137,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) => libc::strdup(dc_tools::to_cstring(res).as_ptr()), Some(res) => dc_tools::to_cstring(res),
None => std::ptr::null_mut(), None => std::ptr::null_mut(),
} }
} }
@@ -1546,7 +1546,3 @@ fn as_opt_str<'a>(s: *const libc::c_char) -> Option<&'a str> {
Some(dc_tools::as_str(s)) Some(dc_tools::as_str(s))
} }
unsafe fn into_cstring(s: impl AsRef<str>) -> *mut libc::c_char {
dc_tools::dc_strdup(dc_tools::to_cstring(s).as_ptr())
}

View File

@@ -139,7 +139,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 = strdup(to_cstring(rs.unwrap_or_default()).as_ptr()); real_spec = to_cstring(rs.unwrap_or_default());
} }
match current_block { match current_block {
8522321847195001863 => {} 8522321847195001863 => {}
@@ -177,10 +177,10 @@ unsafe fn poke_spec(context: &Context, spec: *const libc::c_char) -> libc::c_int
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 = to_cstring(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;
@@ -380,18 +380,16 @@ pub unsafe fn dc_cmdline(context: &Context, line: &str) -> Result<(), failure::E
let mut args = line.splitn(3, ' '); let mut args = line.splitn(3, ' ');
let arg0 = args.next().unwrap_or_default(); let arg0 = args.next().unwrap_or_default();
let arg1 = args.next().unwrap_or_default(); let arg1 = args.next().unwrap_or_default();
let arg1_c = to_cstring(arg1); let arg1_c = if arg1.is_empty() {
let arg1_c_ptr = if arg1.is_empty() {
std::ptr::null() std::ptr::null()
} else { } else {
arg1_c.as_ptr() to_cstring(arg1) as *const _
}; };
let arg2 = args.next().unwrap_or_default(); let arg2 = args.next().unwrap_or_default();
let arg2_c = to_cstring(arg2); let arg2_c = if arg2.is_empty() {
let arg2_c_ptr = if arg2.is_empty() {
std::ptr::null() std::ptr::null()
} else { } else {
arg2_c.as_ptr() to_cstring(arg2) as *const _
}; };
match arg0 { match arg0 {
@@ -497,7 +495,7 @@ pub unsafe fn dc_cmdline(context: &Context, line: &str) -> Result<(), failure::E
ensure!(!arg1.is_empty(), "Argument <file> missing"); ensure!(!arg1.is_empty(), "Argument <file> missing");
dc_close(context); dc_close(context);
ensure!( ensure!(
0 != dc_open(context, arg1_c_ptr, 0 as *const libc::c_char), 0 != dc_open(context, arg1_c, 0 as *const libc::c_char),
"Open failed" "Open failed"
); );
} }
@@ -538,7 +536,7 @@ pub unsafe fn dc_cmdline(context: &Context, line: &str) -> Result<(), failure::E
!arg1.is_empty() && !arg2.is_empty(), !arg1.is_empty() && !arg2.is_empty(),
"Arguments <msg-id> <setup-code> expected" "Arguments <msg-id> <setup-code> expected"
); );
if 0 == dc_continue_key_transfer(context, arg1.parse().unwrap(), arg2_c_ptr) { if 0 == dc_continue_key_transfer(context, arg1.parse().unwrap(), arg2_c) {
bail!("Continue key transfer failed"); bail!("Continue key transfer failed");
} }
} }
@@ -553,7 +551,7 @@ pub unsafe fn dc_cmdline(context: &Context, line: &str) -> Result<(), failure::E
} }
"import-backup" => { "import-backup" => {
ensure!(!arg1.is_empty(), "Argument <backup-file> missing."); ensure!(!arg1.is_empty(), "Argument <backup-file> missing.");
dc_imex(context, 12, arg1_c_ptr, 0 as *const libc::c_char); dc_imex(context, 12, arg1_c, 0 as *const libc::c_char);
} }
"export-keys" => { "export-keys" => {
dc_imex(context, 1, context.get_blobdir(), 0 as *const libc::c_char); dc_imex(context, 1, context.get_blobdir(), 0 as *const libc::c_char);
@@ -590,7 +588,7 @@ pub unsafe fn dc_cmdline(context: &Context, line: &str) -> Result<(), failure::E
free(setup_code as *mut libc::c_void); free(setup_code as *mut libc::c_void);
} }
"poke" => { "poke" => {
ensure!(0 != poke_spec(context, arg1_c_ptr), "Poke failed"); ensure!(0 != poke_spec(context, arg1_c), "Poke failed");
} }
"reset" => { "reset" => {
ensure!(!arg1.is_empty(), "Argument <bits> missing: 1=jobs, 2=peerstates, 4=private keys, 8=rest but server config"); ensure!(!arg1.is_empty(), "Argument <bits> missing: 1=jobs, 2=peerstates, 4=private keys, 8=rest but server config");
@@ -624,7 +622,7 @@ pub unsafe fn dc_cmdline(context: &Context, line: &str) -> Result<(), failure::E
} }
"listchats" | "listarchived" | "chats" => { "listchats" | "listarchived" | "chats" => {
let listflags = if arg0 == "listarchived" { 0x01 } else { 0 }; let listflags = if arg0 == "listarchived" { 0x01 } else { 0 };
let chatlist = dc_get_chatlist(context, listflags, arg1_c_ptr, 0 as uint32_t); let chatlist = dc_get_chatlist(context, listflags, arg1_c, 0 as uint32_t);
ensure!(!chatlist.is_null(), "Failed to retrieve chatlist"); ensure!(!chatlist.is_null(), "Failed to retrieve chatlist");
let mut i: libc::c_int; let mut i: libc::c_int;
@@ -782,8 +780,7 @@ pub unsafe fn dc_cmdline(context: &Context, line: &str) -> Result<(), failure::E
} }
"creategroup" => { "creategroup" => {
ensure!(!arg1.is_empty(), "Argument <name> missing."); ensure!(!arg1.is_empty(), "Argument <name> missing.");
let chat_id_1: libc::c_int = let chat_id_1: libc::c_int = dc_create_group_chat(context, 0, arg1_c) as libc::c_int;
dc_create_group_chat(context, 0, arg1_c_ptr) as libc::c_int;
if chat_id_1 != 0 { if chat_id_1 != 0 {
println!("Group#{} created successfully.", chat_id_1,); println!("Group#{} created successfully.", chat_id_1,);
} else { } else {
@@ -792,8 +789,7 @@ pub unsafe fn dc_cmdline(context: &Context, line: &str) -> Result<(), failure::E
} }
"createverified" => { "createverified" => {
ensure!(!arg1.is_empty(), "Argument <name> missing."); ensure!(!arg1.is_empty(), "Argument <name> missing.");
let chat_id_2: libc::c_int = let chat_id_2: libc::c_int = dc_create_group_chat(context, 1, arg1_c) as libc::c_int;
dc_create_group_chat(context, 1, arg1_c_ptr) as libc::c_int;
if chat_id_2 != 0 { if chat_id_2 != 0 {
println!("VerifiedGroup#{} created successfully.", chat_id_2,); println!("VerifiedGroup#{} created successfully.", chat_id_2,);
} else { } else {
@@ -832,7 +828,7 @@ pub unsafe fn dc_cmdline(context: &Context, line: &str) -> Result<(), failure::E
"groupname" => { "groupname" => {
ensure!(!sel_chat.is_null(), "No chat selected."); ensure!(!sel_chat.is_null(), "No chat selected.");
ensure!(!arg1.is_empty(), "Argument <name> missing."); ensure!(!arg1.is_empty(), "Argument <name> missing.");
if 0 != dc_set_chat_name(context, dc_chat_get_id(sel_chat), arg1_c_ptr) { if 0 != dc_set_chat_name(context, dc_chat_get_id(sel_chat), arg1_c) {
println!("Chat name set"); println!("Chat name set");
} else { } else {
bail!("Failed to set chat name"); bail!("Failed to set chat name");
@@ -846,7 +842,7 @@ pub unsafe fn dc_cmdline(context: &Context, line: &str) -> Result<(), failure::E
context, context,
dc_chat_get_id(sel_chat), dc_chat_get_id(sel_chat),
if !arg1.is_empty() { if !arg1.is_empty() {
arg1_c_ptr arg1_c
} else { } else {
std::ptr::null_mut() std::ptr::null_mut()
}, },
@@ -937,9 +933,11 @@ pub unsafe fn dc_cmdline(context: &Context, line: &str) -> Result<(), failure::E
let msg = to_cstring(format!("{} {}", arg1, arg2)); let msg = to_cstring(format!("{} {}", arg1, arg2));
if 0 != dc_send_text_msg(context, dc_chat_get_id(sel_chat), msg.as_ptr()) { if 0 != dc_send_text_msg(context, dc_chat_get_id(sel_chat), msg) {
println!("Message sent."); println!("Message sent.");
free(msg as *mut _);
} else { } else {
free(msg as *mut _);
bail!("Sending failed."); bail!("Sending failed.");
} }
} }
@@ -960,8 +958,8 @@ pub unsafe fn dc_cmdline(context: &Context, line: &str) -> Result<(), failure::E
ensure!(!arg1.is_empty() && !arg2.is_empty(), "No file given."); ensure!(!arg1.is_empty() && !arg2.is_empty(), "No file given.");
let msg_0 = dc_msg_new(context, if arg0 == "sendimage" { 20 } else { 60 }); let msg_0 = dc_msg_new(context, if arg0 == "sendimage" { 20 } else { 60 });
dc_msg_set_file(msg_0, arg1_c_ptr, 0 as *const libc::c_char); dc_msg_set_file(msg_0, arg1_c, 0 as *const libc::c_char);
dc_msg_set_text(msg_0, arg2_c_ptr); dc_msg_set_text(msg_0, arg2_c);
dc_send_msg(context, dc_chat_get_id(sel_chat), msg_0); dc_send_msg(context, dc_chat_get_id(sel_chat), msg_0);
dc_msg_unref(msg_0); dc_msg_unref(msg_0);
} }
@@ -974,7 +972,7 @@ pub unsafe fn dc_cmdline(context: &Context, line: &str) -> Result<(), failure::E
0 as libc::c_uint 0 as libc::c_uint
}; };
let msglist_0 = dc_search_msgs(context, chat, arg1_c_ptr); let msglist_0 = dc_search_msgs(context, chat, arg1_c);
if !msglist_0.is_null() { if !msglist_0.is_null() {
log_msglist(context, msglist_0); log_msglist(context, msglist_0);
@@ -987,7 +985,7 @@ pub unsafe fn dc_cmdline(context: &Context, line: &str) -> Result<(), failure::E
if !arg1.is_empty() { if !arg1.is_empty() {
let draft_0 = dc_msg_new(context, 10); let draft_0 = dc_msg_new(context, 10);
dc_msg_set_text(draft_0, arg1_c_ptr); dc_msg_set_text(draft_0, arg1_c);
dc_set_draft(context, dc_chat_get_id(sel_chat), draft_0); dc_set_draft(context, dc_chat_get_id(sel_chat), draft_0);
dc_msg_unref(draft_0); dc_msg_unref(draft_0);
println!("Draft saved."); println!("Draft saved.");
@@ -1079,7 +1077,7 @@ pub unsafe fn dc_cmdline(context: &Context, line: &str) -> Result<(), failure::E
} else { } else {
0x2 0x2
}, },
arg1_c_ptr, arg1_c,
); );
if !contacts.is_null() { if !contacts.is_null() {
log_contactlist(context, contacts); log_contactlist(context, contacts);
@@ -1095,13 +1093,13 @@ pub unsafe fn dc_cmdline(context: &Context, line: &str) -> Result<(), failure::E
if !arg2.is_empty() { if !arg2.is_empty() {
let book = dc_mprintf( let book = dc_mprintf(
b"%s\n%s\x00" as *const u8 as *const libc::c_char, b"%s\n%s\x00" as *const u8 as *const libc::c_char,
arg1_c_ptr, arg1_c,
arg2_c_ptr, arg2_c,
); );
dc_add_address_book(context, book); dc_add_address_book(context, book);
free(book as *mut libc::c_void); free(book as *mut libc::c_void);
} else { } else {
if 0 == dc_create_contact(context, 0 as *const libc::c_char, arg1_c_ptr) { if 0 == dc_create_contact(context, 0 as *const libc::c_char, arg1_c) {
bail!("Failed to create contact"); bail!("Failed to create contact");
} }
} }
@@ -1148,7 +1146,7 @@ pub unsafe fn dc_cmdline(context: &Context, line: &str) -> Result<(), failure::E
} }
"checkqr" => { "checkqr" => {
ensure!(!arg1.is_empty(), "Argument <qr-content> missing."); ensure!(!arg1.is_empty(), "Argument <qr-content> missing.");
let res = dc_check_qr(context, arg1_c_ptr); let res = dc_check_qr(context, arg1_c);
println!( println!(
"state={}, id={}, text1={}, text2={}", "state={}, id={}, text1={}, text2={}",
(*res).state as libc::c_int, (*res).state as libc::c_int,
@@ -1176,7 +1174,7 @@ pub unsafe fn dc_cmdline(context: &Context, line: &str) -> Result<(), failure::E
if 0 != dc_read_file( if 0 != dc_read_file(
context, context,
arg1_c_ptr, arg1_c,
&mut buf as *mut *mut libc::c_uchar as *mut *mut libc::c_void, &mut buf as *mut *mut libc::c_uchar as *mut *mut libc::c_void,
&mut buf_bytes, &mut buf_bytes,
) { ) {
@@ -1194,5 +1192,8 @@ pub unsafe fn dc_cmdline(context: &Context, line: &str) -> Result<(), failure::E
dc_chat_unref(sel_chat); dc_chat_unref(sel_chat);
} }
free(arg1_c as *mut _);
free(arg2_c as *mut _);
Ok(()) Ok(())
} }

View File

@@ -398,11 +398,10 @@ fn main_0(args: Vec<String>) -> Result<(), failure::Error> {
if args.len() == 2 { if args.len() == 2 {
if 0 == unsafe { if 0 == unsafe {
dc_open( let a = to_cstring(&args[1]);
&mut context, let res = dc_open(&mut context, a, 0 as *const _);
to_cstring(&args[1]).as_ptr(), free(a as *mut _);
0 as *const libc::c_char, res
)
} { } {
println!("Error: Cannot open {}.", args[0],); println!("Error: Cannot open {}.", args[0],);
} }
@@ -482,11 +481,10 @@ unsafe fn handle_cmd(line: &str, ctx: Arc<RwLock<Context>>) -> Result<ExitResult
let mut args = line.splitn(2, ' '); let mut args = line.splitn(2, ' ');
let arg0 = args.next().unwrap_or_default(); let arg0 = args.next().unwrap_or_default();
let arg1 = args.next().unwrap_or_default(); let arg1 = args.next().unwrap_or_default();
let arg1_c = to_cstring(arg1); let arg1_c = if arg1.is_empty() {
let arg1_c_ptr = if arg1.is_empty() {
std::ptr::null() std::ptr::null()
} else { } else {
arg1_c.as_ptr() to_cstring(arg1)
}; };
match arg0 { match arg0 {
@@ -559,13 +557,15 @@ unsafe fn handle_cmd(line: &str, ctx: Arc<RwLock<Context>>) -> Result<ExitResult
"joinqr" => { "joinqr" => {
start_threads(ctx.clone()); start_threads(ctx.clone());
if !arg0.is_empty() { if !arg0.is_empty() {
dc_join_securejoin(&ctx.read().unwrap(), arg1_c_ptr); dc_join_securejoin(&ctx.read().unwrap(), arg1_c);
} }
} }
"exit" => return Ok(ExitResult::Exit), "exit" => return Ok(ExitResult::Exit),
_ => dc_cmdline(&ctx.read().unwrap(), line)?, _ => dc_cmdline(&ctx.read().unwrap(), line)?,
} }
free(arg1_c as *mut _);
Ok(ExitResult::Continue) Ok(ExitResult::Continue)
} }

View File

@@ -71,7 +71,12 @@ impl Context {
Config::Selfavatar => { Config::Selfavatar => {
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 { dc_get_abs_path(self, to_cstring(p).as_ptr()) }; 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 r = to_string(v); let r = to_string(v);
unsafe { free(v as *mut _) }; unsafe { free(v as *mut _) };
r r

View File

@@ -279,7 +279,7 @@ unsafe fn cb_get_config(
.sql .sql
.get_config(context, as_str(key)) .get_config(context, as_str(key))
.unwrap_or_else(|| to_string(def)); .unwrap_or_else(|| to_string(def));
strdup(to_cstring(res).as_ptr()) to_cstring(res)
} }
pub unsafe fn dc_context_unref(context: &mut Context) { pub unsafe fn dc_context_unref(context: &mut Context) {
@@ -515,7 +515,7 @@ pub unsafe fn dc_get_info(context: &Context) -> *mut libc::c_char {
fingerprint_str, fingerprint_str,
); );
strdup(to_cstring(res).as_ptr()) to_cstring(res)
} }
pub unsafe fn dc_get_version_str() -> *mut libc::c_char { pub unsafe fn dc_get_version_str() -> *mut libc::c_char {

View File

@@ -374,7 +374,7 @@ pub unsafe fn dc_array_get_string(
} }
res res
}); });
strdup(to_cstring(res).as_ptr()) to_cstring(res)
} }
/// return comma-separated value-string from integer array /// return comma-separated value-string from integer array
@@ -396,7 +396,7 @@ pub unsafe fn dc_arr_to_string(arr: *const uint32_t, cnt: libc::c_int) -> *mut l
res res
}, },
); );
strdup(to_cstring(res).as_ptr()) to_cstring(res)
} }
#[cfg(test)] #[cfg(test)]

View File

@@ -130,15 +130,19 @@ pub fn dc_chat_load_from_db(chat: *mut Chat, chat_id: u32) -> bool {
c.type_0 = row.get(1)?; c.type_0 = row.get(1)?;
c.name = { c.name = {
let raw: String = row.get(2)?; let raw: String = row.get(2)?;
unsafe { strdup(to_cstring(raw).as_ptr()) } unsafe { to_cstring(raw) }
}; };
c.grpid = { c.grpid = {
let raw: String = row.get(3)?; let raw: String = row.get(3)?;
unsafe { strdup(to_cstring(raw).as_ptr()) } unsafe { to_cstring(raw) }
}; };
let packed: String = row.get(4)?; let packed: String = row.get(4)?;
unsafe { dc_param_set_packed((*chat).param, to_cstring(&packed).as_ptr()) }; unsafe {
let p = to_cstring(&packed);
dc_param_set_packed((*chat).param, p);
free(p as *mut _);
};
c.archived = row.get(5)?; c.archived = row.get(5)?;
c.blocked = row.get(6)?; c.blocked = row.get(6)?;
c.gossiped_timestamp = row.get(7)?; c.gossiped_timestamp = row.get(7)?;
@@ -496,8 +500,9 @@ unsafe fn prepare_msg_raw(
} else { } else {
0 as *mut libc::c_char 0 as *mut libc::c_char
}, },
from_c.as_ptr(), from_c,
); );
free(from_c as *mut _);
if (*chat).type_0 == 100 { if (*chat).type_0 == 100 {
if let Some(id) = context.sql.query_row_col( if let Some(id) = context.sql.query_row_col(
@@ -761,9 +766,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 = dc_strdup(to_cstring(row.get::<_, String>(0)?).as_ptr()); *parent_rfc724_mid = to_cstring(row.get::<_, String>(0)?);
*parent_in_reply_to = dc_strdup(to_cstring(row.get::<_, String>(1)?).as_ptr()); *parent_in_reply_to = to_cstring(row.get::<_, String>(1)?);
*parent_references = dc_strdup(to_cstring(row.get::<_, String>(2)?).as_ptr()); *parent_references = to_cstring(row.get::<_, String>(2)?);
Ok(()) Ok(())
}, },
) )
@@ -779,12 +784,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 = *parent_rfc724_mid = to_cstring(row.get::<_, String>(0)?);
dc_strdup(to_cstring(row.get::<_, String>(0)?).as_ptr()); *parent_in_reply_to = to_cstring(row.get::<_, String>(1)?);
*parent_in_reply_to = *parent_references = to_cstring(row.get::<_, String>(2)?);
dc_strdup(to_cstring(row.get::<_, String>(1)?).as_ptr());
*parent_references =
dc_strdup(to_cstring(row.get::<_, String>(2)?).as_ptr());
Ok(()) Ok(())
}, },
) )
@@ -823,7 +825,8 @@ unsafe fn last_msg_in_chat_encrypted(
if let Some(packed) = packed { if let Some(packed) = packed {
let msg_param = dc_param_new(); let msg_param = dc_param_new();
let packed_c = to_cstring(packed); let packed_c = to_cstring(packed);
dc_param_set_packed(msg_param, packed_c.as_ptr()); dc_param_set_packed(msg_param, packed_c);
free(packed_c as *mut _);
if 0 != dc_param_exists(msg_param, 'c' as i32) { if 0 != dc_param_exists(msg_param, 'c' as i32) {
last_is_encrypted = 1; last_is_encrypted = 1;
@@ -2090,7 +2093,7 @@ 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 = dc_strdup(to_cstring(ret_raw).as_ptr()); ret = to_cstring(ret_raw);
} 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 = dc_stock_str((*chat).context, 8) ret = dc_stock_str((*chat).context, 8)

View File

@@ -1098,12 +1098,14 @@ unsafe fn moz_autoconfigure(
tag_config: 0, tag_config: 0,
}; };
let xml_raw = read_autoconf_file(context, to_cstring(url).as_ptr()); let url_c = to_cstring(url);
let xml_raw = read_autoconf_file(context, url_c);
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 = dc_strdup(to_cstring(&param_in.addr).as_ptr()); moz_ac.in_emaillocalpart = to_cstring(&param_in.addr);
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() {
@@ -1160,11 +1162,13 @@ 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);
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,
to_cstring(&(*moz_ac).in_0.addr).as_ptr(), addr,
); );
free(addr as *mut libc::c_void);
dc_str_replace( dc_str_replace(
&mut val, &mut val,
b"%EMAILLOCALPART%\x00" as *const u8 as *const libc::c_char, b"%EMAILLOCALPART%\x00" as *const u8 as *const libc::c_char,
@@ -1298,7 +1302,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 { libc::strdup(to_cstring(res).as_ptr()) }, Ok(res) => unsafe { to_cstring(res) },
Err(_err) => { Err(_err) => {
info!(context, 0, "Can\'t read file.",); info!(context, 0, "Can\'t read file.",);
@@ -1314,7 +1318,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 = dc_strdup(to_cstring(url__).as_ptr()); let mut url = to_cstring(url__);
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

@@ -277,15 +277,12 @@ 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 = dc_stock_str((*contact).context, 2); (*contact).name = dc_stock_str((*contact).context, 2);
(*contact).addr = dc_strdup( (*contact).addr = to_cstring(
to_cstring( (*contact)
(*contact) .context
.context .sql
.sql .get_config((*contact).context, "configured_addr")
.get_config((*contact).context, "configured_addr") .unwrap_or_default(),
.unwrap_or_default(),
)
.as_ptr(),
); );
true true
} else { } else {
@@ -294,11 +291,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 = dc_strdup(to_cstring(row.get::<_, String>(0)?).as_ptr()); (*contact).name = to_cstring(row.get::<_, String>(0)?);
(*contact).addr = dc_strdup(to_cstring(row.get::<_, String>(1)?).as_ptr()); (*contact).addr = to_cstring(row.get::<_, String>(1)?);
(*contact).origin = row.get(2)?; (*contact).origin = row.get(2)?;
(*contact).blocked = row.get(3)?; (*contact).blocked = row.get(3)?;
(*contact).authname = dc_strdup(to_cstring(row.get::<_, String>(4)?).as_ptr()); (*contact).authname = to_cstring(row.get::<_, String>(4)?);
Ok(()) Ok(())
} }
).is_ok() ).is_ok()
@@ -735,7 +732,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);
strdup(to_cstring(ret).as_ptr()) to_cstring(ret)
} }
unsafe fn cat_fingerprint( unsafe fn cat_fingerprint(
@@ -905,7 +902,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 { dc_strdup(to_cstring(avatar).as_ptr()) }; image_abs = unsafe { to_cstring(avatar) };
} }
} }
// 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);
strdup(to_cstring(dehtml.strbuilder).as_ptr()) to_cstring(dehtml.strbuilder)
} }
unsafe fn dehtml_text_cb( unsafe fn dehtml_text_cb(

View File

@@ -184,7 +184,7 @@ pub unsafe fn dc_e2ee_encrypt(
b"Autocrypt-Gossip\x00" as *const u8 b"Autocrypt-Gossip\x00" as *const u8
as *const libc::c_char, as *const libc::c_char,
), ),
strdup(header.as_ptr()), header,
), ),
); );
} }

View File

@@ -309,7 +309,7 @@ pub unsafe fn dc_create_setup_code(_context: &Context) -> *mut libc::c_char {
); );
} }
strdup(to_cstring(ret).as_ptr()) to_cstring(ret)
} }
// TODO should return bool /rtn // TODO should return bool /rtn
@@ -539,7 +539,7 @@ pub unsafe fn dc_normalize_setup_code(
p1 = p1.offset(1); p1 = p1.offset(1);
} }
strdup(to_cstring(out).as_ptr()) to_cstring(out)
} }
pub unsafe fn dc_job_do_DC_JOB_IMEX_IMAP(context: &Context, job: *mut dc_job_t) { pub unsafe fn dc_job_do_DC_JOB_IMEX_IMAP(context: &Context, job: *mut dc_job_t) {
@@ -895,7 +895,8 @@ unsafe fn export_backup(context: &Context, dir: *const libc::c_char) -> libc::c_
.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 = to_cstring(res);
let dest_pathNfilename = dc_get_fine_pathNfilename(context, dir, buffer.as_ptr()); let dest_pathNfilename = dc_get_fine_pathNfilename(context, dir, buffer);
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.",);
@@ -1094,6 +1095,7 @@ 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;
@@ -1121,8 +1123,9 @@ 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();
let name_c = to_cstring(name_f.to_string_lossy()); free(name_c as *mut libc::c_void);
suffix = dc_get_filesuffix_lc(name_c.as_ptr()); name_c = to_cstring(name_f.to_string_lossy());
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
{ {
@@ -1132,7 +1135,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.as_ptr(), name_c,
); );
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);
@@ -1170,12 +1173,7 @@ unsafe fn import_self_keys(context: &Context, dir_name: *const libc::c_char) ->
} }
} }
set_default = 1; set_default = 1;
if !strstr( if !strstr(name_c, b"legacy\x00" as *const u8 as *const libc::c_char).is_null() {
name_c.as_ptr(),
b"legacy\x00" as *const u8 as *const libc::c_char,
)
.is_null()
{
info!( info!(
context, context,
0, 0,
@@ -1200,6 +1198,7 @@ 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

@@ -99,7 +99,9 @@ unsafe fn dc_job_perform(context: &Context, thread: libc::c_int, probe_network:
}; };
let packed: String = row.get(3)?; let packed: String = row.get(3)?;
dc_param_set_packed(job.param, to_cstring(packed).as_ptr()); let packed_c = to_cstring(packed);
dc_param_set_packed(job.param, packed_c);
free(packed_c as *mut _);
info!(context, 0, "DONE jobs query_maps row"); info!(context, 0, "DONE jobs query_maps row");
Ok(job) Ok(job)
}, },

View File

@@ -215,8 +215,10 @@ pub fn dc_get_locations(
if 0 != (*loc).msg_id { if 0 != (*loc).msg_id {
let txt: String = row.get(9)?; let txt: String = row.get(9)?;
let txt_c = to_cstring(txt); let txt_c = to_cstring(txt);
if 0 != is_marker(txt_c.as_ptr()) { if 0 != is_marker(txt_c) {
(*loc).marker = strdup(txt_c.as_ptr()); (*loc).marker = txt_c;
} else {
free(txt_c as *mut _);
} }
} }
Ok(loc) Ok(loc)
@@ -330,9 +332,9 @@ pub fn dc_get_location_kml(
} }
if 0 != success { if 0 != success {
unsafe { strdup(to_cstring(ret).as_ptr()) } unsafe { to_cstring(ret) }
} else { } else {
0 as *mut libc::c_char std::ptr::null_mut()
} }
} }
@@ -344,7 +346,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();
strdup(to_cstring(res).as_ptr()) to_cstring(res)
} }
pub unsafe fn dc_get_message_kml( pub unsafe fn dc_get_message_kml(

View File

@@ -161,24 +161,20 @@ pub unsafe fn dc_mimefactory_load_msg(
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 = to_cstring(addr);
if clist_search_string_nocase( if clist_search_string_nocase((*factory).recipients_addr, addr_c) == 0 {
(*factory).recipients_addr,
addr_c.as_ptr(),
) == 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() {
dc_strdup(to_cstring(authname).as_ptr()) to_cstring(authname)
} else { } else {
0 as *mut libc::c_char std::ptr::null_mut()
} as *mut libc::c_void, } as *mut libc::c_void,
); );
clist_insert_after( clist_insert_after(
(*factory).recipients_addr, (*factory).recipients_addr,
(*(*factory).recipients_addr).last, (*(*factory).recipients_addr).last,
dc_strdup(addr_c.as_ptr()) as *mut libc::c_void, addr_c as *mut libc::c_void,
); );
} }
} }
@@ -241,8 +237,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 = dc_strdup(to_cstring(in_reply_to).as_ptr()); (*factory).in_reply_to = to_cstring(in_reply_to);
(*factory).references = dc_strdup(to_cstring(references).as_ptr()); (*factory).references = to_cstring(references);
} }
Err(err) => { Err(err) => {
error!( error!(
@@ -266,32 +262,24 @@ 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 = strdup( (*factory).from_addr = to_cstring(
to_cstring( context
context .sql
.sql .get_config(context, "configured_addr")
.get_config(context, "configured_addr") .unwrap_or_default(),
.unwrap_or_default(),
)
.as_ptr(),
); );
(*factory).from_displayname = strdup(
to_cstring( (*factory).from_displayname = to_cstring(
context context
.sql .sql
.get_config(context, "displayname") .get_config(context, "displayname")
.unwrap_or_default(), .unwrap_or_default(),
)
.as_ptr(),
); );
(*factory).selfstatus = strdup( (*factory).selfstatus = to_cstring(
to_cstring( context
context .sql
.sql .get_config(context, "selfstatus")
.get_config(context, "selfstatus") .unwrap_or_default(),
.unwrap_or_default(),
)
.as_ptr(),
); );
if (*factory).selfstatus.is_null() { if (*factory).selfstatus.is_null() {
(*factory).selfstatus = dc_stock_str((*factory).context, 13) (*factory).selfstatus = dc_stock_str((*factory).context, 13)
@@ -1178,7 +1166,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 = strdup(to_cstring(res).as_ptr()); filename_to_send = to_cstring(res);
} else if (*msg).type_0 == 40 { } else if (*msg).type_0 == 40 {
filename_to_send = dc_get_filename(pathNfilename) filename_to_send = dc_get_filename(pathNfilename)
} else if (*msg).type_0 == 20 || (*msg).type_0 == 21 { } else if (*msg).type_0 == 20 || (*msg).type_0 == 21 {

View File

@@ -1341,8 +1341,9 @@ 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);
desired_filename = let parts_c = to_cstring(filename_parts);
dc_decode_ext_header(to_cstring(filename_parts).as_ptr()); desired_filename = dc_decode_ext_header(parts_c);
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

@@ -63,7 +63,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 strdup(to_cstring(ret).as_ptr()); return to_cstring(ret);
} }
let rawtxt = rawtxt.unwrap(); let rawtxt = rawtxt.unwrap();
let rawtxt = dc_truncate_str(rawtxt.trim(), 100000); let rawtxt = dc_truncate_str(rawtxt.trim(), 100000);
@@ -91,7 +91,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 strdup(to_cstring(ret).as_ptr()); return to_cstring(ret);
} }
context context
@@ -209,7 +209,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);
strdup(to_cstring(ret).as_ptr()) to_cstring(ret)
} }
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> {
@@ -445,9 +445,9 @@ 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 = dc_strdup(to_cstring(row.get::<_, String>(1)?).as_ptr()); (*msg).rfc724_mid = to_cstring(row.get::<_, String>(1)?);
(*msg).in_reply_to = dc_strdup(to_cstring(row.get::<_, String>(2)?).as_ptr()); (*msg).in_reply_to = to_cstring(row.get::<_, String>(2)?);
(*msg).server_folder = dc_strdup(to_cstring(row.get::<_, String>(3)?).as_ptr()); (*msg).server_folder = to_cstring(row.get::<_, String>(3)?);
(*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)?;
@@ -459,10 +459,10 @@ 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 = dc_strdup(to_cstring(row.get::<_, String>(15).unwrap_or_default()).as_ptr()); (*msg).text = to_cstring(row.get::<_, String>(15).unwrap_or_default());
dc_param_set_packed( dc_param_set_packed(
(*msg).param, (*msg).param,
to_cstring(row.get::<_, String>(16)?).as_ptr() to_cstring(row.get::<_, String>(16)?)
); );
(*msg).starred = row.get(17)?; (*msg).starred = row.get(17)?;
(*msg).hidden = row.get(18)?; (*msg).hidden = row.get(18)?;
@@ -494,7 +494,10 @@ 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 {
dc_strdup_keep_null(to_cstring(headers).as_ptr()) let h = to_cstring(headers);
let res = dc_strdup_keep_null(h);
free(h as *mut _);
res
} else { } else {
std::ptr::null_mut() std::ptr::null_mut()
} }
@@ -691,7 +694,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);
dc_strdup(to_cstring(res).as_ptr()) to_cstring(res)
} }
pub unsafe fn dc_msg_get_filename(msg: *const dc_msg_t) -> *mut libc::c_char { pub unsafe fn dc_msg_get_filename(msg: *const dc_msg_t) -> *mut libc::c_char {
@@ -1357,9 +1360,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 { unsafe { *ret_server_folder = to_cstring(row.get::<_, String>(0)?) };
*ret_server_folder = dc_strdup(to_cstring(row.get::<_, String>(0)?).as_ptr())
};
} }
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

@@ -239,13 +239,8 @@ pub unsafe fn dc_check_qr(context: &Context, qr: *const libc::c_char) -> *mut dc
if addr.is_null() || invitenumber.is_null() || auth.is_null() { if addr.is_null() || invitenumber.is_null() || auth.is_null() {
if let Some(peerstate) = peerstate { if let Some(peerstate) = peerstate {
(*qr_parsed).state = 210i32; (*qr_parsed).state = 210i32;
let c_addr = peerstate let addr_ptr = if let Some(ref addr) = peerstate.addr {
.addr to_cstring(addr)
.as_ref()
.map(to_cstring)
.unwrap_or_default();
let addr_ptr = if peerstate.addr.is_some() {
c_addr.as_ptr()
} else { } else {
std::ptr::null() std::ptr::null()
}; };
@@ -256,6 +251,7 @@ pub unsafe fn dc_check_qr(context: &Context, qr: *const libc::c_char) -> *mut dc
0x80i32, 0x80i32,
0 as *mut libc::c_int, 0 as *mut libc::c_int,
); );
free(addr_ptr as *mut _);
dc_create_or_lookup_nchat_by_contact_id( dc_create_or_lookup_nchat_by_contact_id(
context, context,
(*qr_parsed).id, (*qr_parsed).id,

View File

@@ -739,11 +739,9 @@ pub unsafe fn dc_receive_imf(
} }
if 0 != mime_parser.is_send_by_messenger || 0 != mdn_consumed { if 0 != mime_parser.is_send_by_messenger || 0 != mdn_consumed {
let param = dc_param_new(); let param = dc_param_new();
dc_param_set( let server_folder_c = to_cstring(server_folder.as_ref());
param, dc_param_set(param, 'Z' as i32, server_folder_c);
'Z' as i32, free(server_folder_c as *mut _);
to_cstring(server_folder.as_ref()).as_ptr(),
);
dc_param_set_int(param, 'z' as i32, server_uid as i32); dc_param_set_int(param, 'z' as i32, server_uid as i32);
if 0 != mime_parser.is_send_by_messenger if 0 != mime_parser.is_send_by_messenger
&& 0 != context && 0 != context
@@ -1518,9 +1516,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]);
let result_cstring = to_cstring(result_hex); unsafe { to_cstring(result_hex) as *const _ }
unsafe { strdup(result_cstring.as_ptr()) }
} }
unsafe fn search_chat_ids_by_contact_ids( unsafe fn search_chat_ids_by_contact_ids(
@@ -1604,8 +1600,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 = *failure_reason = to_cstring(format!("{}. See \"Info\" for details.", reason));
strdup(to_cstring(format!("{}. See \"Info\" for details.", reason)).as_ptr());
warn!(context, 0, "{}", reason); warn!(context, 0, "{}", reason);
}; };

View File

@@ -62,7 +62,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 {
strdup(to_cstring(qr).as_ptr()) to_cstring(qr)
} else { } else {
std::ptr::null_mut() std::ptr::null_mut()
} }
@@ -939,15 +939,15 @@ pub unsafe fn dc_handle_degrade_event(context: &Context, peerstate: &Peerstate)
&mut contact_chat_id, &mut contact_chat_id,
0 as *mut libc::c_int, 0 as *mut libc::c_int,
); );
let c_addr = peerstate.addr.as_ref().map(to_cstring).unwrap_or_default(); let c_addr_ptr = if let Some(ref addr) = peerstate.addr {
let c_addr_ptr = if peerstate.addr.is_some() { to_cstring(addr)
c_addr.as_ptr()
} else { } else {
std::ptr::null_mut() std::ptr::null_mut()
}; };
let msg = dc_stock_str_repl_string(context, 37, c_addr_ptr); let msg = dc_stock_str_repl_string(context, 37, c_addr_ptr);
dc_add_device_msg(context, contact_chat_id, msg); dc_add_device_msg(context, contact_chat_id, msg);
free(msg as *mut libc::c_void); free(msg as *mut libc::c_void);
free(c_addr_ptr as *mut _);
context.call_cb( context.call_cb(
Event::CHAT_MODIFIED, Event::CHAT_MODIFIED,
contact_chat_id as uintptr_t, contact_chat_id as uintptr_t,

View File

@@ -238,7 +238,7 @@ unsafe fn dc_simplify_simplify_plain_text(
} }
dc_free_splitted_lines(lines); dc_free_splitted_lines(lines);
strdup(to_cstring(ret).as_ptr()) to_cstring(ret)
} }
/** /**

View File

@@ -712,7 +712,8 @@ unsafe fn print_hex(target: *mut libc::c_char, cur: *const libc::c_char) {
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 = to_cstring(format!("={}", &hex::encode_upper(bytes)[..2]));
libc::memcpy(target as *mut _, raw.as_ptr() as *const _, 4); libc::memcpy(target as *mut _, raw as *const _, 4);
free(raw as *mut libc::c_void);
} }
#[cfg(test)] #[cfg(test)]

View File

@@ -1,7 +1,6 @@
use crate::context::Context; use crate::context::Context;
use crate::dc_tools::*; use crate::dc_tools::*;
use crate::sql; use crate::sql;
use crate::x::strdup;
// Token namespaces // Token namespaces
pub type dc_tokennamespc_t = usize; pub type dc_tokennamespc_t = usize;
@@ -34,16 +33,16 @@ pub fn dc_token_lookup(
namespc: dc_tokennamespc_t, namespc: dc_tokennamespc_t,
foreign_id: u32, foreign_id: u32,
) -> *mut libc::c_char { ) -> *mut libc::c_char {
if let Some(token) = context.sql.query_row_col::<_, String>( context
context, .sql
"SELECT token FROM tokens WHERE namespc=? AND foreign_id=?;", .query_row_col::<_, String>(
params![namespc as i32, foreign_id as i32], context,
0, "SELECT token FROM tokens WHERE namespc=? AND foreign_id=?;",
) { params![namespc as i32, foreign_id as i32],
unsafe { strdup(to_cstring(token).as_ptr()) } 0,
} else { )
std::ptr::null_mut() .map(|s| unsafe { to_cstring(s) })
} .unwrap_or_else(|| std::ptr::null_mut())
} }
pub fn dc_token_exists( pub fn dc_token_exists(

View File

@@ -3,11 +3,14 @@ macro_rules! info {
($ctx:expr, $data1:expr, $msg:expr) => { ($ctx:expr, $data1:expr, $msg:expr) => {
info!($ctx, $data1, $msg,) info!($ctx, $data1, $msg,)
}; };
($ctx:expr, $data1:expr, $msg:expr, $($args:expr),* $(,)?) => {{ ($ctx:expr, $data1:expr, $msg:expr, $($args:expr),* $(,)?) => {
let formatted = format!($msg, $($args),*); #[allow(unused_unsafe)]
let formatted_c = $crate::dc_tools::to_cstring(formatted); unsafe {
$ctx.call_cb($crate::constants::Event::INFO, $data1 as libc::uintptr_t, let formatted = format!($msg, $($args),*);
formatted_c.as_ptr() as libc::uintptr_t) let formatted_c = $crate::dc_tools::to_cstring(formatted);
$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);
}}; }};
} }
@@ -17,11 +20,14 @@ macro_rules! warn {
warn!($ctx, $data1, $msg,) warn!($ctx, $data1, $msg,)
}; };
($ctx:expr, $data1:expr, $msg:expr, $($args:expr),* $(,)?) => { ($ctx:expr, $data1:expr, $msg:expr, $($args:expr),* $(,)?) => {
let formatted = format!($msg, $($args),*); #[allow(unused_unsafe)]
let formatted_c = $crate::dc_tools::to_cstring(formatted); unsafe {
$ctx.call_cb($crate::constants::Event::WARNING, $data1 as libc::uintptr_t, let formatted = format!($msg, $($args),*);
formatted_c.as_ptr() as libc::uintptr_t) let formatted_c = $crate::dc_tools::to_cstring(formatted);
}; $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) ;
}};
} }
#[macro_export] #[macro_export]
@@ -30,11 +36,14 @@ macro_rules! error {
error!($ctx, $data1, $msg,) error!($ctx, $data1, $msg,)
}; };
($ctx:expr, $data1:expr, $msg:expr, $($args:expr),* $(,)?) => { ($ctx:expr, $data1:expr, $msg:expr, $($args:expr),* $(,)?) => {
#[allow(unused_unsafe)]
unsafe {
let formatted = format!($msg, $($args),*); let formatted = format!($msg, $($args),*);
let formatted_c = $crate::dc_tools::to_cstring(formatted); let formatted_c = $crate::dc_tools::to_cstring(formatted);
$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_ptr() as libc::uintptr_t) formatted_c as libc::uintptr_t);
}; libc::free(formatted_c as *mut libc::c_void);
}};
} }
#[macro_export] #[macro_export]
@@ -43,9 +52,12 @@ macro_rules! log_event {
log_event!($ctx, $data1, $msg,) log_event!($ctx, $data1, $msg,)
}; };
($ctx:expr, $event:expr, $data1:expr, $msg:expr, $($args:expr),* $(,)?) => { ($ctx:expr, $event:expr, $data1:expr, $msg:expr, $($args:expr),* $(,)?) => {
let formatted = format!($msg, $($args),*); #[allow(unused_unsafe)]
let formatted_c = $crate::dc_tools::to_cstring(formatted); unsafe {
$ctx.call_cb($event, $data1 as libc::uintptr_t, let formatted = format!($msg, $($args),*);
formatted_c.as_ptr() as libc::uintptr_t) let formatted_c = $crate::dc_tools::to_cstring(formatted);
}; $ctx.call_cb($event, $data1 as libc::uintptr_t,
formatted_c as libc::uintptr_t);
libc::free(formatted_c as *mut libc::c_void);
}};
} }

View File

@@ -1005,31 +1005,36 @@ pub fn housekeeping(context: &Context) {
} }
let entry = entry.unwrap(); let entry = entry.unwrap();
let name_f = entry.file_name(); let name_f = entry.file_name();
let name_c = to_cstring(name_f.to_string_lossy()); let name_c = unsafe { to_cstring(name_f.to_string_lossy()) };
if unsafe { if unsafe { is_file_in_use(&mut files_in_use, 0 as *const libc::c_char, name_c) }
is_file_in_use(&mut files_in_use, 0 as *const libc::c_char, name_c.as_ptr()) || unsafe {
} || unsafe { is_file_in_use(
is_file_in_use( &mut files_in_use,
&mut files_in_use, b".increation\x00" as *const u8 as *const libc::c_char,
b".increation\x00" as *const u8 as *const libc::c_char, name_c,
name_c.as_ptr(), )
) }
} || unsafe { || unsafe {
is_file_in_use( is_file_in_use(
&mut files_in_use, &mut files_in_use,
b".waveform\x00" as *const u8 as *const libc::c_char, b".waveform\x00" as *const u8 as *const libc::c_char,
name_c.as_ptr(), name_c,
) )
} || unsafe { }
is_file_in_use( || unsafe {
&mut files_in_use, is_file_in_use(
b"-preview.jpg\x00" as *const u8 as *const libc::c_char, &mut files_in_use,
name_c.as_ptr(), b"-preview.jpg\x00" as *const u8 as *const libc::c_char,
) name_c,
} { )
}
{
unsafe { free(name_c as *mut _) };
continue; continue;
} }
unsafe { free(name_c as *mut _) };
unreferenced_count += 1; unreferenced_count += 1;
match std::fs::metadata(entry.path()) { match std::fs::metadata(entry.path()) {
@@ -1061,8 +1066,11 @@ pub fn housekeeping(context: &Context) {
unreferenced_count, unreferenced_count,
entry.file_name() entry.file_name()
); );
let path = to_cstring(entry.path().to_str().unwrap()); unsafe {
unsafe { dc_delete_file(context, path.as_ptr()) }; let path = to_cstring(entry.path().to_str().unwrap());
dc_delete_file(context, path);
free(path as *mut _);
}
} }
} }
Err(err) => { Err(err) => {
@@ -1120,14 +1128,16 @@ fn maybe_add_from_param(
context context
.sql .sql
.query_row(query, NO_PARAMS, |row| { .query_row(query, NO_PARAMS, |row| {
let v = to_cstring(row.get::<_, String>(0)?);
unsafe { unsafe {
dc_param_set_packed(param, v.as_ptr() as *const libc::c_char); let v = to_cstring(row.get::<_, String>(0)?);
let file = dc_param_get(param, param_id, 0 as *const libc::c_char); dc_param_set_packed(param, v as *const _);
let file = dc_param_get(param, param_id, 0 as *const _);
if !file.is_null() { if !file.is_null() {
maybe_add_file(files_in_use, as_str(file)); maybe_add_file(files_in_use, as_str(file));
free(file as *mut libc::c_void); free(file as *mut libc::c_void);
} }
free(v as *mut _);
} }
Ok(()) Ok(())
}) })

View File

@@ -175,7 +175,7 @@ unsafe fn stress_functions(context: &Context) {
"content" "content"
); );
free(buf); free(buf as *mut _);
assert_ne!( assert_ne!(
0, 0,
dc_delete_file( dc_delete_file(
@@ -952,24 +952,29 @@ 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 contacts = dc_get_contacts(&context.ctx, 0, to_cstring("some2").as_ptr()); let name = to_cstring("some2");
let contacts = dc_get_contacts(&context.ctx, 0, name);
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 id = dc_create_contact( let name = to_cstring("bob");
&context.ctx, let email = to_cstring("bob@mail.de");
to_cstring("bob").as_ptr(), let id = dc_create_contact(&context.ctx, name, email);
to_cstring("bob@mail.de").as_ptr(),
);
assert_ne!(id, 0); assert_ne!(id, 0);
let contacts = dc_get_contacts(&context.ctx, 0, to_cstring("bob").as_ptr()); let contacts = dc_get_contacts(&context.ctx, 0, name);
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 contacts = dc_get_contacts(&context.ctx, 0, to_cstring("alice").as_ptr()); let name2 = to_cstring("alice");
let contacts = dc_get_contacts(&context.ctx, 0, name2);
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 _);
} }
} }
@@ -977,11 +982,12 @@ fn test_get_contacts() {
fn test_chat() { fn test_chat() {
unsafe { unsafe {
let context = create_test_context(); let context = create_test_context();
let contact1 = dc_create_contact( let name = to_cstring("bob");
&context.ctx, let email = to_cstring("bob@mail.de");
to_cstring("bob").as_ptr(),
to_cstring("bob@mail.de").as_ptr(), let contact1 = dc_create_contact(&context.ctx, name, email);
); 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);