refactor(chat): remove C strings from the public interface

This commit is contained in:
dignifiedquire
2019-08-16 00:48:06 +02:00
parent 25e97df641
commit 9b1a74cc22
7 changed files with 109 additions and 140 deletions

View File

@@ -13,6 +13,7 @@ extern crate num_traits;
use num_traits::{FromPrimitive, ToPrimitive}; use num_traits::{FromPrimitive, ToPrimitive};
use std::convert::TryInto; use std::convert::TryInto;
use std::ptr;
use std::str::FromStr; use std::str::FromStr;
use deltachat::contact::Contact; use deltachat::contact::Contact;
@@ -603,7 +604,7 @@ pub unsafe extern "C" fn dc_create_group_chat(
return 0; return 0;
}; };
chat::create_group_chat(context, verified, name) chat::create_group_chat(context, verified, as_str(name))
.unwrap_or_log_default(context, "Failed to create group chat") .unwrap_or_log_default(context, "Failed to create group chat")
} }
@@ -667,7 +668,7 @@ pub unsafe extern "C" fn dc_set_chat_profile_image(
assert!(chat_id > constants::DC_CHAT_ID_LAST_SPECIAL as u32); assert!(chat_id > constants::DC_CHAT_ID_LAST_SPECIAL as u32);
let context = &*context; let context = &*context;
chat::set_chat_profile_image(context, chat_id, image) chat::set_chat_profile_image(context, chat_id, as_str(image))
} }
#[no_mangle] #[no_mangle]
@@ -1325,7 +1326,10 @@ pub unsafe extern "C" fn dc_chat_get_profile_image(chat: *mut dc_chat_t) -> *mut
assert!(!chat.is_null()); assert!(!chat.is_null());
let chat = &*chat; let chat = &*chat;
chat.get_profile_image() match chat.get_profile_image() {
Some(i) => i.strdup(),
None => ptr::null_mut(),
}
} }
#[no_mangle] #[no_mangle]

View File

@@ -726,13 +726,13 @@ 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 = chat::create_group_chat(context, VerifiedStatus::Unverified, arg1_c)?; let chat_id = chat::create_group_chat(context, VerifiedStatus::Unverified, arg1)?;
println!("Group#{} created successfully.", chat_id); println!("Group#{} created successfully.", chat_id);
} }
"createverified" => { "createverified" => {
ensure!(!arg1.is_empty(), "Argument <name> missing."); ensure!(!arg1.is_empty(), "Argument <name> missing.");
let chat_id = chat::create_group_chat(context, VerifiedStatus::Verified, arg1_c)?; let chat_id = chat::create_group_chat(context, VerifiedStatus::Verified, arg1)?;
println!("VerifiedGroup#{} created successfully.", chat_id); println!("VerifiedGroup#{} created successfully.", chat_id);
} }
@@ -778,15 +778,8 @@ pub unsafe fn dc_cmdline(context: &Context, line: &str) -> Result<(), failure::E
ensure!(sel_chat.is_some(), "No chat selected."); ensure!(sel_chat.is_some(), "No chat selected.");
ensure!(!arg1.is_empty(), "Argument <image> missing."); ensure!(!arg1.is_empty(), "Argument <image> missing.");
if 0 != chat::set_chat_profile_image( if 0 != chat::set_chat_profile_image(context, sel_chat.as_ref().unwrap().get_id(), arg1)
context, {
sel_chat.as_ref().unwrap().get_id(),
if !arg1.is_empty() {
arg1_c
} else {
std::ptr::null_mut()
},
) {
println!("Chat image set"); println!("Chat image set");
} else { } else {
bail!("Failed to set chat image"); bail!("Failed to set chat image");

View File

@@ -219,25 +219,21 @@ impl<'a> Chat<'a> {
Ok(()) Ok(())
} }
pub unsafe fn get_profile_image(&self) -> *mut libc::c_char { pub unsafe fn get_profile_image(&self) -> Option<String> {
let mut image_abs: *mut libc::c_char = 0 as *mut libc::c_char;
if let Some(image_rel) = self.param.get(Param::ProfileImage) { if let Some(image_rel) = self.param.get(Param::ProfileImage) {
if !image_rel.is_empty() { if !image_rel.is_empty() {
image_abs = dc_get_abs_path(self.context, image_rel); return Some(to_string(dc_get_abs_path(self.context, image_rel)));
} }
} else if self.typ == Chattype::Single { } else if self.typ == Chattype::Single {
let contacts = get_chat_contacts(self.context, self.id); let contacts = get_chat_contacts(self.context, self.id);
if !contacts.is_empty() { if !contacts.is_empty() {
if let Ok(contact) = Contact::get_by_id(self.context, contacts[0]) { if let Ok(contact) = Contact::get_by_id(self.context, contacts[0]) {
if let Some(img) = contact.get_profile_image() { return contact.get_profile_image();
image_abs = img.strdup();
}
} }
} }
} }
image_abs None
} }
pub fn get_color(&self) -> u32 { pub fn get_color(&self) -> u32 {
@@ -1391,15 +1387,12 @@ pub fn get_chat_contacts(context: &Context, chat_id: u32) -> Vec<u32> {
pub unsafe fn create_group_chat( pub unsafe fn create_group_chat(
context: &Context, context: &Context,
verified: VerifiedStatus, verified: VerifiedStatus,
chat_name: *const libc::c_char, chat_name: impl AsRef<str>,
) -> Result<u32, Error> { ) -> Result<u32, Error> {
ensure!( ensure!(!chat_name.as_ref().is_empty(), "Invalid chat name");
!chat_name.is_null() && *chat_name.offset(0) as libc::c_int != 0,
"Invalid chat name"
);
let draft_txt = let draft_txt =
CString::new(context.stock_string_repl_str(StockMessage::NewGroupDraft, as_str(chat_name))) CString::new(context.stock_string_repl_str(StockMessage::NewGroupDraft, &chat_name))
.unwrap(); .unwrap();
let grpid = dc_create_id(); let grpid = dc_create_id();
@@ -1413,7 +1406,7 @@ pub unsafe fn create_group_chat(
} else { } else {
Chattype::Group Chattype::Group
}, },
as_str(chat_name), chat_name.as_ref(),
grpid grpid
], ],
)?; )?;
@@ -1785,7 +1778,7 @@ pub unsafe fn set_chat_name(
pub unsafe fn set_chat_profile_image( pub unsafe fn set_chat_profile_image(
context: &Context, context: &Context,
chat_id: u32, chat_id: u32,
new_image: *const libc::c_char, new_image: impl AsRef<str>,
) -> libc::c_int { ) -> libc::c_int {
let mut OK_TO_CONTINUE = true; let mut OK_TO_CONTINUE = true;
let mut success: libc::c_int = 0i32; let mut success: libc::c_int = 0i32;
@@ -1809,8 +1802,8 @@ pub unsafe fn set_chat_profile_image(
); );
} else { } else {
/* we should respect this - whatever we send to the group, it gets discarded anyway! */ /* we should respect this - whatever we send to the group, it gets discarded anyway! */
if !new_image.is_null() { if !new_image.as_ref().is_empty() {
let mut img = to_string(new_image); let mut img = new_image.as_ref().to_string();
if !dc_make_rel_and_copy(context, &mut img) { if !dc_make_rel_and_copy(context, &mut img) {
OK_TO_CONTINUE = false; OK_TO_CONTINUE = false;
} }
@@ -1991,7 +1984,7 @@ pub fn get_chat_cnt(context: &Context) -> usize {
pub unsafe fn get_chat_id_by_grpid( pub unsafe fn get_chat_id_by_grpid(
context: &Context, context: &Context,
grpid: *const libc::c_char, grpid: impl AsRef<str>,
ret_blocked: Option<&mut Blocked>, ret_blocked: Option<&mut Blocked>,
ret_verified: *mut libc::c_int, ret_verified: *mut libc::c_int,
) -> u32 { ) -> u32 {
@@ -2003,7 +1996,7 @@ pub unsafe fn get_chat_id_by_grpid(
.sql .sql
.query_row( .query_row(
"SELECT id, blocked, type FROM chats WHERE grpid=?;", "SELECT id, blocked, type FROM chats WHERE grpid=?;",
params![as_str(grpid)], params![grpid.as_ref()],
|row| { |row| {
let chat_id = row.get(0)?; let chat_id = row.get(0)?;
@@ -2020,10 +2013,7 @@ pub unsafe fn get_chat_id_by_grpid(
.unwrap_or_default() .unwrap_or_default()
} }
pub fn add_device_msg(context: &Context, chat_id: u32, text: *const libc::c_char) { pub fn add_device_msg(context: &Context, chat_id: u32, text: impl AsRef<str>) {
if text.is_null() {
return;
}
let rfc724_mid = unsafe { let rfc724_mid = unsafe {
dc_create_outgoing_rfc724_mid( dc_create_outgoing_rfc724_mid(
ptr::null(), ptr::null(),
@@ -2040,7 +2030,7 @@ pub fn add_device_msg(context: &Context, chat_id: u32, text: *const libc::c_char
dc_create_smeared_timestamp(context), dc_create_smeared_timestamp(context),
Viewtype::Text, Viewtype::Text,
DC_STATE_IN_NOTICED, DC_STATE_IN_NOTICED,
as_str(text), text.as_ref(),
as_str(rfc724_mid), as_str(rfc724_mid),
] ]
).is_err() { ).is_err() {

View File

@@ -1,5 +1,3 @@
use std::ffi::CString;
use quick_xml; use quick_xml;
use quick_xml::events::{BytesEnd, BytesStart, BytesText}; use quick_xml::events::{BytesEnd, BytesStart, BytesText};
@@ -106,14 +104,9 @@ pub unsafe fn dc_send_locations_to_chat(
(*msg).param.set_int(Param::Cmd, 8); (*msg).param.set_int(Param::Cmd, 8);
chat::send_msg(context, chat_id, msg).unwrap(); chat::send_msg(context, chat_id, msg).unwrap();
} else if 0 == seconds && is_sending_locations_before { } else if 0 == seconds && is_sending_locations_before {
let stock_str = CString::new(context.stock_system_msg( let stock_str =
StockMessage::MsgLocationDisabled, context.stock_system_msg(StockMessage::MsgLocationDisabled, "", "", 0);
"", chat::add_device_msg(context, chat_id, stock_str);
"",
0,
))
.unwrap();
chat::add_device_msg(context, chat_id, stock_str.as_ptr());
} }
context.call_cb( context.call_cb(
Event::CHAT_MODIFIED, Event::CHAT_MODIFIED,
@@ -736,8 +729,8 @@ pub unsafe fn dc_job_do_DC_JOB_MAYBE_SEND_LOC_ENDED(context: &Context, job: &mut
"UPDATE chats SET locations_send_begin=0, locations_send_until=0 WHERE id=?", "UPDATE chats SET locations_send_begin=0, locations_send_until=0 WHERE id=?",
params![chat_id as i32], params![chat_id as i32],
).is_ok() { ).is_ok() {
let stock_str = CString::new(context.stock_system_msg(StockMessage::MsgLocationDisabled, "", "", 0)).unwrap(); let stock_str = context.stock_system_msg(StockMessage::MsgLocationDisabled, "", "", 0);
chat::add_device_msg(context, chat_id, stock_str.as_ptr()); chat::add_device_msg(context, chat_id, stock_str);
context.call_cb( context.call_cb(
Event::CHAT_MODIFIED, Event::CHAT_MODIFIED,
chat_id as usize, chat_id as usize,

View File

@@ -35,7 +35,7 @@ pub unsafe fn dc_check_qr(context: &Context, qr: *const libc::c_char) -> *mut dc
let mut auth: *mut libc::c_char = 0 as *mut libc::c_char; let mut auth: *mut libc::c_char = 0 as *mut libc::c_char;
let mut qr_parsed: *mut dc_lot_t = dc_lot_new(); let mut qr_parsed: *mut dc_lot_t = dc_lot_new();
let mut chat_id: uint32_t = 0i32 as uint32_t; let mut chat_id: uint32_t = 0i32 as uint32_t;
let mut device_msg: *mut libc::c_char = 0 as *mut libc::c_char; let mut device_msg = "".to_string();
let mut grpid: *mut libc::c_char = 0 as *mut libc::c_char; let mut grpid: *mut libc::c_char = 0 as *mut libc::c_char;
let mut grpname: *mut libc::c_char = 0 as *mut libc::c_char; let mut grpname: *mut libc::c_char = 0 as *mut libc::c_char;
(*qr_parsed).state = 0i32; (*qr_parsed).state = 0i32;
@@ -238,13 +238,10 @@ pub unsafe fn dc_check_qr(context: &Context, qr: *const libc::c_char) -> *mut dc
) )
.unwrap_or_default(); .unwrap_or_default();
chat_id = id; chat_id = id;
device_msg = dc_mprintf( device_msg = format!("{} verified.", peerstate.addr.unwrap_or_default());
b"%s verified.\x00" as *const u8 as *const libc::c_char,
peerstate.addr,
)
} else { } else {
(*qr_parsed).text1 = dc_format_fingerprint_c(fingerprint); (*qr_parsed).text1 = dc_format_fingerprint_c(fingerprint);
(*qr_parsed).state = 230i32 (*qr_parsed).state = 230i32;
} }
} else { } else {
if !grpid.is_null() && !grpname.is_null() { if !grpid.is_null() && !grpname.is_null() {
@@ -287,7 +284,7 @@ pub unsafe fn dc_check_qr(context: &Context, qr: *const libc::c_char) -> *mut dc
(*qr_parsed).state = 330i32; (*qr_parsed).state = 330i32;
(*qr_parsed).text1 = dc_strdup(qr) (*qr_parsed).text1 = dc_strdup(qr)
} }
if !device_msg.is_null() { if !device_msg.is_empty() {
chat::add_device_msg(context, chat_id, device_msg); chat::add_device_msg(context, chat_id, device_msg);
} }
} }
@@ -298,7 +295,6 @@ pub unsafe fn dc_check_qr(context: &Context, qr: *const libc::c_char) -> *mut dc
free(name as *mut libc::c_void); free(name as *mut libc::c_void);
free(invitenumber as *mut libc::c_void); free(invitenumber as *mut libc::c_void);
free(auth as *mut libc::c_void); free(auth as *mut libc::c_void);
free(device_msg as *mut libc::c_void);
free(grpname as *mut libc::c_void); free(grpname as *mut libc::c_void);
free(grpid as *mut libc::c_void); free(grpid as *mut libc::c_void);

View File

@@ -1045,7 +1045,7 @@ unsafe fn create_or_lookup_group(
let mut chat_id = 0; let mut chat_id = 0;
let mut chat_id_blocked = Blocked::Not; let mut chat_id_blocked = Blocked::Not;
let mut chat_id_verified = 0; let mut chat_id_verified = 0;
let mut grpid = std::ptr::null_mut(); let mut grpid = "".to_string();
let mut grpname = std::ptr::null_mut(); let mut grpname = std::ptr::null_mut();
let to_ids_cnt = to_ids.len(); let to_ids_cnt = to_ids.len();
let mut recreate_member_list = 0; let mut recreate_member_list = 0;
@@ -1059,14 +1059,12 @@ unsafe fn create_or_lookup_group(
let mut better_msg: String = From::from(""); let mut better_msg: String = From::from("");
let mut failure_reason = std::ptr::null_mut(); let mut failure_reason = std::ptr::null_mut();
let cleanup = |grpid: *mut libc::c_char, let cleanup = |grpname: *mut libc::c_char,
grpname: *mut libc::c_char,
failure_reason: *mut libc::c_char, failure_reason: *mut libc::c_char,
ret_chat_id: *mut uint32_t, ret_chat_id: *mut uint32_t,
ret_chat_id_blocked: &mut Blocked, ret_chat_id_blocked: &mut Blocked,
chat_id: u32, chat_id: u32,
chat_id_blocked: Blocked| { chat_id_blocked: Blocked| {
free(grpid.cast());
free(grpname.cast()); free(grpname.cast());
free(failure_reason.cast()); free(failure_reason.cast());
@@ -1089,40 +1087,44 @@ unsafe fn create_or_lookup_group(
// search the grpid in the header // search the grpid in the header
let optional_field = dc_mimeparser_lookup_optional_field(mime_parser, "Chat-Group-ID"); let optional_field = dc_mimeparser_lookup_optional_field(mime_parser, "Chat-Group-ID");
if !optional_field.is_null() { if !optional_field.is_null() {
grpid = dc_strdup((*optional_field).fld_value) grpid = to_string((*optional_field).fld_value)
} }
if grpid.is_null() { if grpid.is_empty() {
if let Some(field) = lookup_field(mime_parser, "Message-ID", MAILIMF_FIELD_MESSAGE_ID) { if let Some(field) = lookup_field(mime_parser, "Message-ID", MAILIMF_FIELD_MESSAGE_ID) {
let fld_message_id = (*field).fld_data.fld_message_id; let fld_message_id = (*field).fld_data.fld_message_id;
if !fld_message_id.is_null() { if !fld_message_id.is_null() {
if let Some(extracted_grpid) = if let Some(extracted_grpid) =
dc_extract_grpid_from_rfc724_mid(as_str((*fld_message_id).mid_value)) dc_extract_grpid_from_rfc724_mid(as_str((*fld_message_id).mid_value))
{ {
grpid = extracted_grpid.strdup(); grpid = extracted_grpid.to_string();
} else { } else {
grpid = std::ptr::null_mut(); grpid = "".to_string();
} }
} }
} }
if grpid.is_null() { if grpid.is_empty() {
if let Some(field) = lookup_field(mime_parser, "In-Reply-To", MAILIMF_FIELD_IN_REPLY_TO) if let Some(field) = lookup_field(mime_parser, "In-Reply-To", MAILIMF_FIELD_IN_REPLY_TO)
{ {
let fld_in_reply_to = (*field).fld_data.fld_in_reply_to; let fld_in_reply_to = (*field).fld_data.fld_in_reply_to;
if !fld_in_reply_to.is_null() { if !fld_in_reply_to.is_null() {
grpid = dc_extract_grpid_from_rfc724_mid_list((*fld_in_reply_to).mid_list) grpid = to_string(dc_extract_grpid_from_rfc724_mid_list(
(*fld_in_reply_to).mid_list,
));
} }
} }
if grpid.is_null() { if grpid.is_empty() {
if let Some(field) = if let Some(field) =
lookup_field(mime_parser, "References", MAILIMF_FIELD_REFERENCES) lookup_field(mime_parser, "References", MAILIMF_FIELD_REFERENCES)
{ {
let fld_references = (*field).fld_data.fld_references; let fld_references = (*field).fld_data.fld_references;
if !fld_references.is_null() { if !fld_references.is_null() {
grpid = dc_extract_grpid_from_rfc724_mid_list((*fld_references).mid_list) grpid = to_string(dc_extract_grpid_from_rfc724_mid_list(
(*fld_references).mid_list,
));
} }
} }
if grpid.is_null() { if grpid.is_empty() {
create_or_lookup_adhoc_group( create_or_lookup_adhoc_group(
context, context,
mime_parser, mime_parser,
@@ -1134,7 +1136,6 @@ unsafe fn create_or_lookup_group(
&mut chat_id_blocked, &mut chat_id_blocked,
); );
cleanup( cleanup(
grpid,
grpname, grpname,
failure_reason, failure_reason,
ret_chat_id, ret_chat_id,
@@ -1227,7 +1228,7 @@ unsafe fn create_or_lookup_group(
// check, if we have a chat with this group ID // check, if we have a chat with this group ID
chat_id = chat::get_chat_id_by_grpid( chat_id = chat::get_chat_id_by_grpid(
context, context,
grpid, &grpid,
Some(&mut chat_id_blocked), Some(&mut chat_id_blocked),
&mut chat_id_verified, &mut chat_id_verified,
); );
@@ -1252,8 +1253,7 @@ unsafe fn create_or_lookup_group(
} }
// check if the group does not exist but should be created // check if the group does not exist but should be created
group_explicitly_left = group_explicitly_left = chat::is_group_explicitly_left(context, &grpid).unwrap_or_default();
chat::is_group_explicitly_left(context, as_str(grpid)).unwrap_or_default();
let self_addr = context let self_addr = context
.sql .sql
@@ -1261,7 +1261,7 @@ unsafe fn create_or_lookup_group(
.unwrap_or_default(); .unwrap_or_default();
if chat_id == 0 if chat_id == 0
&& 0 == dc_mimeparser_is_mailinglist_message(mime_parser) && 0 == dc_mimeparser_is_mailinglist_message(mime_parser)
&& !grpid.is_null() && !grpid.is_empty()
&& !grpname.is_null() && !grpname.is_null()
// otherwise, a pending "quit" message may pop up // otherwise, a pending "quit" message may pop up
&& X_MrRemoveFromGrp.is_null() && X_MrRemoveFromGrp.is_null()
@@ -1269,9 +1269,9 @@ unsafe fn create_or_lookup_group(
&& (!group_explicitly_left && (!group_explicitly_left
|| !X_MrAddToGrp.is_null() && addr_cmp(&self_addr, as_str(X_MrAddToGrp))) || !X_MrAddToGrp.is_null() && addr_cmp(&self_addr, as_str(X_MrAddToGrp)))
{ {
let mut create_verified: libc::c_int = 0; let mut create_verified = VerifiedStatus::Unverified;
if !dc_mimeparser_lookup_field(mime_parser, "Chat-Verified").is_null() { if !dc_mimeparser_lookup_field(mime_parser, "Chat-Verified").is_null() {
create_verified = 1; create_verified = VerifiedStatus::Verified;
if 0 == check_verified_properties( if 0 == check_verified_properties(
context, context,
mime_parser, mime_parser,
@@ -1284,7 +1284,6 @@ unsafe fn create_or_lookup_group(
} }
if 0 == allow_creation { if 0 == allow_creation {
cleanup( cleanup(
grpid,
grpname, grpname,
failure_reason, failure_reason,
ret_chat_id, ret_chat_id,
@@ -1294,7 +1293,7 @@ unsafe fn create_or_lookup_group(
); );
return; return;
} }
chat_id = create_group_record(context, grpid, grpname, create_blocked, create_verified); chat_id = create_group_record(context, &grpid, grpname, create_blocked, create_verified);
chat_id_blocked = create_blocked; chat_id_blocked = create_blocked;
recreate_member_list = 1; recreate_member_list = 1;
} }
@@ -1317,7 +1316,6 @@ unsafe fn create_or_lookup_group(
); );
} }
cleanup( cleanup(
grpid,
grpname, grpname,
failure_reason, failure_reason,
ret_chat_id, ret_chat_id,
@@ -1457,7 +1455,6 @@ unsafe fn create_or_lookup_group(
} }
cleanup( cleanup(
grpid,
grpname, grpname,
failure_reason, failure_reason,
ret_chat_id, ret_chat_id,
@@ -1482,16 +1479,13 @@ unsafe fn create_or_lookup_adhoc_group(
// group matching the to-list or if we can create one // group matching the to-list or if we can create one
let mut chat_id = 0; let mut chat_id = 0;
let mut chat_id_blocked = Blocked::Not; let mut chat_id_blocked = Blocked::Not;
let mut grpid = 0 as *mut libc::c_char;
let mut grpname = 0 as *mut libc::c_char; let mut grpname = 0 as *mut libc::c_char;
let cleanup = |grpid: *mut libc::c_char, let cleanup = |grpname: *mut libc::c_char,
grpname: *mut libc::c_char,
ret_chat_id: *mut uint32_t, ret_chat_id: *mut uint32_t,
ret_chat_id_blocked: &mut Blocked, ret_chat_id_blocked: &mut Blocked,
chat_id: u32, chat_id: u32,
chat_id_blocked: Blocked| { chat_id_blocked: Blocked| {
free(grpid as *mut libc::c_void);
free(grpname as *mut libc::c_void); free(grpname as *mut libc::c_void);
if !ret_chat_id.is_null() { if !ret_chat_id.is_null() {
@@ -1504,7 +1498,6 @@ unsafe fn create_or_lookup_adhoc_group(
if to_ids.is_empty() || 0 != dc_mimeparser_is_mailinglist_message(mime_parser) { if to_ids.is_empty() || 0 != dc_mimeparser_is_mailinglist_message(mime_parser) {
// too few contacts or a mailinglist // too few contacts or a mailinglist
cleanup( cleanup(
grpid,
grpname, grpname,
ret_chat_id, ret_chat_id,
ret_chat_id_blocked, ret_chat_id_blocked,
@@ -1524,7 +1517,6 @@ unsafe fn create_or_lookup_adhoc_group(
if member_ids.len() < 3 { if member_ids.len() < 3 {
// too few contacts given // too few contacts given
cleanup( cleanup(
grpid,
grpname, grpname,
ret_chat_id, ret_chat_id,
ret_chat_id_blocked, ret_chat_id_blocked,
@@ -1554,7 +1546,6 @@ unsafe fn create_or_lookup_adhoc_group(
chat_id_blocked = id_blocked; chat_id_blocked = id_blocked;
/* success, chat found */ /* success, chat found */
cleanup( cleanup(
grpid,
grpname, grpname,
ret_chat_id, ret_chat_id,
ret_chat_id_blocked, ret_chat_id_blocked,
@@ -1567,7 +1558,6 @@ unsafe fn create_or_lookup_adhoc_group(
if 0 == allow_creation { if 0 == allow_creation {
cleanup( cleanup(
grpid,
grpname, grpname,
ret_chat_id, ret_chat_id,
ret_chat_id_blocked, ret_chat_id_blocked,
@@ -1581,10 +1571,9 @@ unsafe fn create_or_lookup_adhoc_group(
// create a new ad-hoc group // create a new ad-hoc group
// - there is no need to check if this group exists; otherwise we would have caught it above // - there is no need to check if this group exists; otherwise we would have caught it above
grpid = create_adhoc_grp_id(context, &member_ids); let grpid = create_adhoc_grp_id(context, &member_ids);
if grpid.is_null() { if grpid.is_empty() {
cleanup( cleanup(
grpid,
grpname, grpname,
ret_chat_id, ret_chat_id,
ret_chat_id_blocked, ret_chat_id_blocked,
@@ -1604,7 +1593,13 @@ unsafe fn create_or_lookup_adhoc_group(
} }
// create group record // create group record
chat_id = create_group_record(context, grpid, grpname, create_blocked, 0); chat_id = create_group_record(
context,
&grpid,
grpname,
create_blocked,
VerifiedStatus::Unverified,
);
chat_id_blocked = create_blocked; chat_id_blocked = create_blocked;
for &member_id in &member_ids { for &member_id in &member_ids {
chat::add_to_chat_contacts_table(context, chat_id, member_id); chat::add_to_chat_contacts_table(context, chat_id, member_id);
@@ -1613,7 +1608,6 @@ unsafe fn create_or_lookup_adhoc_group(
context.call_cb(Event::CHAT_MODIFIED, chat_id as uintptr_t, 0 as uintptr_t); context.call_cb(Event::CHAT_MODIFIED, chat_id as uintptr_t, 0 as uintptr_t);
cleanup( cleanup(
grpid,
grpname, grpname,
ret_chat_id, ret_chat_id,
ret_chat_id_blocked, ret_chat_id_blocked,
@@ -1624,19 +1618,23 @@ unsafe fn create_or_lookup_adhoc_group(
fn create_group_record( fn create_group_record(
context: &Context, context: &Context,
grpid: *const libc::c_char, grpid: impl AsRef<str>,
grpname: *const libc::c_char, grpname: *const libc::c_char,
create_blocked: Blocked, create_blocked: Blocked,
create_verified: libc::c_int, create_verified: VerifiedStatus,
) -> u32 { ) -> u32 {
if sql::execute( if sql::execute(
context, context,
&context.sql, &context.sql,
"INSERT INTO chats (type, name, grpid, blocked) VALUES(?, ?, ?, ?);", "INSERT INTO chats (type, name, grpid, blocked) VALUES(?, ?, ?, ?);",
params![ params![
if 0 != create_verified { 130 } else { 120 }, if VerifiedStatus::Unverified != create_verified {
Chattype::VerifiedGroup
} else {
Chattype::Group
},
as_str(grpname), as_str(grpname),
as_str(grpid), grpid.as_ref(),
create_blocked, create_blocked,
], ],
) )
@@ -1645,10 +1643,10 @@ fn create_group_record(
return 0; return 0;
} }
sql::get_rowid(context, &context.sql, "chats", "grpid", as_str(grpid)) sql::get_rowid(context, &context.sql, "chats", "grpid", grpid.as_ref())
} }
unsafe fn create_adhoc_grp_id(context: &Context, member_ids: &Vec<u32>) -> *mut libc::c_char { fn create_adhoc_grp_id(context: &Context, member_ids: &Vec<u32>) -> String {
/* algorithm: /* algorithm:
- sort normalized, lowercased, e-mail addresses alphabetically - sort normalized, lowercased, e-mail addresses alphabetically
- put all e-mail addresses into a single string, separate the address by a single comma - put all e-mail addresses into a single string, separate the address by a single comma
@@ -1684,14 +1682,13 @@ unsafe fn create_adhoc_grp_id(context: &Context, member_ids: &Vec<u32>) -> *mut
) )
.unwrap_or_else(|_| member_cs); .unwrap_or_else(|_| member_cs);
hex_hash(&members) as *mut _ hex_hash(&members)
} }
fn hex_hash(s: impl AsRef<str>) -> *const libc::c_char { fn hex_hash(s: impl AsRef<str>) -> String {
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]); hex::encode(&result[..8])
unsafe { result_hex.strdup() as *const _ }
} }
#[allow(non_snake_case)] #[allow(non_snake_case)]
@@ -2168,8 +2165,7 @@ mod tests {
fn test_hex_hash() { fn test_hex_hash() {
let data = "hello world"; let data = "hello world";
let res_c = hex_hash(data); let res = hex_hash(data);
let res = to_string(res_c);
assert_eq!(res, "b94d27b9934d3e08"); assert_eq!(res, "b94d27b9934d3e08");
} }
} }

View File

@@ -1,5 +1,3 @@
use std::ffi::CString;
use mmime::mailimf_types::*; use mmime::mailimf_types::*;
use percent_encoding::{utf8_percent_encode, NON_ALPHANUMERIC}; use percent_encoding::{utf8_percent_encode, NON_ALPHANUMERIC};
@@ -187,9 +185,9 @@ pub unsafe fn dc_join_securejoin(context: &Context, qr: *const libc::c_char) ->
(*qr_scan).auth, (*qr_scan).auth,
own_fingerprint, own_fingerprint,
if 0 != join_vg { if 0 != join_vg {
(*qr_scan).text2 as_str((*qr_scan).text2)
} else { } else {
0 as *mut libc::c_char ""
}, },
); );
free(own_fingerprint as *mut libc::c_void); free(own_fingerprint as *mut libc::c_void);
@@ -205,7 +203,7 @@ pub unsafe fn dc_join_securejoin(context: &Context, qr: *const libc::c_char) ->
}, },
(*qr_scan).invitenumber, (*qr_scan).invitenumber,
0 as *const libc::c_char, 0 as *const libc::c_char,
0 as *const libc::c_char, "",
); );
} }
@@ -228,9 +226,12 @@ pub unsafe fn dc_join_securejoin(context: &Context, qr: *const libc::c_char) ->
bob.expects = 0; bob.expects = 0;
if bob.status == 1 { if bob.status == 1 {
if 0 != join_vg { if 0 != join_vg {
ret_chat_id = ret_chat_id = chat::get_chat_id_by_grpid(
chat::get_chat_id_by_grpid(context, (*qr_scan).text2, None, 0 as *mut libc::c_int) context,
as libc::c_int to_string((*qr_scan).text2),
None,
0 as *mut libc::c_int,
) as libc::c_int
} else { } else {
ret_chat_id = contact_chat_id as libc::c_int ret_chat_id = contact_chat_id as libc::c_int
} }
@@ -250,7 +251,7 @@ unsafe fn send_handshake_msg(
step: *const libc::c_char, step: *const libc::c_char,
param2: *const libc::c_char, param2: *const libc::c_char,
fingerprint: *const libc::c_char, fingerprint: *const libc::c_char,
grpid: *const libc::c_char, grpid: impl AsRef<str>,
) { ) {
let mut msg: *mut dc_msg_t = dc_msg_new_untyped(context); let mut msg: *mut dc_msg_t = dc_msg_new_untyped(context);
(*msg).type_0 = Viewtype::Text; (*msg).type_0 = Viewtype::Text;
@@ -268,8 +269,8 @@ unsafe fn send_handshake_msg(
if !fingerprint.is_null() { if !fingerprint.is_null() {
(*msg).param.set(Param::Arg3, as_str(fingerprint)); (*msg).param.set(Param::Arg3, as_str(fingerprint));
} }
if !grpid.is_null() { if !grpid.as_ref().is_empty() {
(*msg).param.set(Param::Arg4, as_str(grpid)); (*msg).param.set(Param::Arg4, grpid.as_ref());
} }
if strcmp(step, b"vg-request\x00" as *const u8 as *const libc::c_char) == 0i32 if strcmp(step, b"vg-request\x00" as *const u8 as *const libc::c_char) == 0i32
|| strcmp(step, b"vc-request\x00" as *const u8 as *const libc::c_char) == 0i32 || strcmp(step, b"vc-request\x00" as *const u8 as *const libc::c_char) == 0i32
@@ -339,7 +340,7 @@ pub unsafe fn dc_handle_securejoin_handshake(
let mut own_fingerprint: *mut libc::c_char = 0 as *mut libc::c_char; let mut own_fingerprint: *mut libc::c_char = 0 as *mut libc::c_char;
let contact_chat_id: u32; let contact_chat_id: u32;
let contact_chat_id_blocked: Blocked; let contact_chat_id_blocked: Blocked;
let mut grpid: *mut libc::c_char = 0 as *mut libc::c_char; let mut grpid = "".to_string();
let mut ret: libc::c_int = 0i32; let mut ret: libc::c_int = 0i32;
if !(contact_id <= 9i32 as libc::c_uint) { if !(contact_id <= 9i32 as libc::c_uint) {
@@ -399,7 +400,7 @@ pub unsafe fn dc_handle_securejoin_handshake(
}, },
0 as *const libc::c_char, 0 as *const libc::c_char,
0 as *const libc::c_char, 0 as *const libc::c_char,
0 as *const libc::c_char, "",
); );
current_block = 10256747982273457880; current_block = 10256747982273457880;
} }
@@ -429,7 +430,7 @@ pub unsafe fn dc_handle_securejoin_handshake(
scanned_fingerprint_of_alice = dc_strdup((*scan).fingerprint); scanned_fingerprint_of_alice = dc_strdup((*scan).fingerprint);
auth = dc_strdup((*scan).auth); auth = dc_strdup((*scan).auth);
if 0 != join_vg { if 0 != join_vg {
grpid = dc_strdup((*scan).text2) grpid = to_string((*scan).text2);
} }
} }
if !encrypted_and_signed(mimeparser, scanned_fingerprint_of_alice) { if !encrypted_and_signed(mimeparser, scanned_fingerprint_of_alice) {
@@ -569,15 +570,15 @@ pub unsafe fn dc_handle_securejoin_handshake(
600i32 as uintptr_t, 600i32 as uintptr_t,
); );
if 0 != join_vg { if 0 != join_vg {
grpid = dc_strdup(lookup_field(mimeparser, "Secure-Join-Group")); grpid = to_string(lookup_field(mimeparser, "Secure-Join-Group"));
let group_chat_id: uint32_t = chat::get_chat_id_by_grpid( let group_chat_id: uint32_t = chat::get_chat_id_by_grpid(
context, context,
grpid, &grpid,
None, None,
0 as *mut libc::c_int, 0 as *mut libc::c_int,
); );
if group_chat_id == 0i32 as libc::c_uint { if group_chat_id == 0i32 as libc::c_uint {
error!(context, 0, "Chat {} not found.", as_str(grpid),); error!(context, 0, "Chat {} not found.", &grpid);
current_block = 4378276786830486580; current_block = 4378276786830486580;
} else { } else {
chat::add_contact_to_chat_ex( chat::add_contact_to_chat_ex(
@@ -595,7 +596,7 @@ pub unsafe fn dc_handle_securejoin_handshake(
b"vc-contact-confirm\x00" as *const u8 as *const libc::c_char, b"vc-contact-confirm\x00" as *const u8 as *const libc::c_char,
0 as *const libc::c_char, 0 as *const libc::c_char,
0 as *const libc::c_char, 0 as *const libc::c_char,
0 as *const libc::c_char, "",
); );
context.call_cb( context.call_cb(
Event::SECUREJOIN_INVITER_PROGRESS, Event::SECUREJOIN_INVITER_PROGRESS,
@@ -637,7 +638,7 @@ pub unsafe fn dc_handle_securejoin_handshake(
let scan = context.bob.clone().read().unwrap().qr_scan; let scan = context.bob.clone().read().unwrap().qr_scan;
scanned_fingerprint_of_alice = dc_strdup((*scan).fingerprint); scanned_fingerprint_of_alice = dc_strdup((*scan).fingerprint);
if 0 != join_vg { if 0 != join_vg {
grpid = dc_strdup((*scan).text2) grpid = to_string((*scan).text2);
} }
} }
let mut vg_expect_encrypted: libc::c_int = 1i32; let mut vg_expect_encrypted: libc::c_int = 1i32;
@@ -725,7 +726,7 @@ pub unsafe fn dc_handle_securejoin_handshake(
as *const libc::c_char, as *const libc::c_char,
0 as *const libc::c_char, 0 as *const libc::c_char,
0 as *const libc::c_char, 0 as *const libc::c_char,
0 as *const libc::c_char, "",
); );
} }
end_bobs_joining(context, 1i32); end_bobs_joining(context, 1i32);
@@ -784,7 +785,6 @@ pub unsafe fn dc_handle_securejoin_handshake(
free(scanned_fingerprint_of_alice as *mut libc::c_void); free(scanned_fingerprint_of_alice as *mut libc::c_void);
free(auth as *mut libc::c_void); free(auth as *mut libc::c_void);
free(own_fingerprint as *mut libc::c_void); free(own_fingerprint as *mut libc::c_void);
free(grpid as *mut libc::c_void);
ret ret
} }
@@ -802,9 +802,8 @@ unsafe fn secure_connection_established(context: &Context, contact_chat_id: uint
} else { } else {
"?" "?"
}; };
let msg = let msg = context.stock_string_repl_str(StockMessage::ContactVerified, addr);
CString::new(context.stock_string_repl_str(StockMessage::ContactVerified, addr)).unwrap(); chat::add_device_msg(context, contact_chat_id, msg);
chat::add_device_msg(context, contact_chat_id, msg.as_ptr());
context.call_cb( context.call_cb(
Event::CHAT_MODIFIED, Event::CHAT_MODIFIED,
contact_chat_id as uintptr_t, contact_chat_id as uintptr_t,
@@ -844,9 +843,9 @@ unsafe fn could_not_establish_secure_connection(
"?" "?"
}, },
); );
let msg_c = CString::new(msg.as_str()).unwrap();
chat::add_device_msg(context, contact_chat_id, msg_c.as_ptr()); chat::add_device_msg(context, contact_chat_id, &msg);
error!(context, 0, "{} ({})", msg, as_str(details)); error!(context, 0, "{} ({})", &msg, as_str(details));
} }
unsafe fn mark_peer_as_verified( unsafe fn mark_peer_as_verified(
@@ -931,11 +930,9 @@ pub unsafe fn dc_handle_degrade_event(context: &Context, peerstate: &Peerstate)
Some(ref addr) => &addr, Some(ref addr) => &addr,
None => "", None => "",
}; };
let msg = CString::new( let msg = context.stock_string_repl_str(StockMessage::ContactSetupChanged, peeraddr);
context.stock_string_repl_str(StockMessage::ContactSetupChanged, peeraddr),
) chat::add_device_msg(context, contact_chat_id, msg);
.unwrap();
chat::add_device_msg(context, contact_chat_id, msg.as_ptr());
context.call_cb( context.call_cb(
Event::CHAT_MODIFIED, Event::CHAT_MODIFIED,
contact_chat_id as uintptr_t, contact_chat_id as uintptr_t,