diff --git a/deltachat-ffi/src/lib.rs b/deltachat-ffi/src/lib.rs index 30493becc..881186c20 100644 --- a/deltachat-ffi/src/lib.rs +++ b/deltachat-ffi/src/lib.rs @@ -986,12 +986,13 @@ pub unsafe extern "C" fn dc_stop_ongoing_process(context: *mut dc_context_t) { pub unsafe extern "C" fn dc_check_qr( context: *mut dc_context_t, qr: *mut libc::c_char, -) -> *mut dc_lot::dc_lot_t { +) -> *mut dc_lot_t { assert!(!context.is_null()); assert!(!qr.is_null()); let context = &*context; - dc_qr::dc_check_qr(context, qr) + let lot = dc_qr::dc_check_qr(context, qr); + Box::into_raw(Box::new(lot)) } #[no_mangle] @@ -1264,13 +1265,14 @@ pub unsafe extern "C" fn dc_chatlist_get_summary<'a>( chatlist: *mut dc_chatlist_t<'a>, index: libc::size_t, chat: *mut dc_chat_t<'a>, -) -> *mut dc_lot::dc_lot_t { +) -> *mut dc_lot_t { assert!(!chatlist.is_null()); let chat = if chat.is_null() { None } else { Some(&*chat) }; let list = &*chatlist; - list.get_summary(index as usize, chat) + let lot = list.get_summary(index as usize, chat); + Box::into_raw(Box::new(lot)) } #[no_mangle] @@ -1542,11 +1544,12 @@ pub unsafe extern "C" fn dc_msg_get_showpadlock(msg: *mut dc_msg::dc_msg_t) -> l pub unsafe extern "C" fn dc_msg_get_summary<'a>( msg: *mut dc_msg::dc_msg_t<'a>, chat: *mut dc_chat_t<'a>, -) -> *mut dc_lot::dc_lot_t { +) -> *mut dc_lot_t { assert!(!msg.is_null()); let chat = if chat.is_null() { None } else { Some(&*chat) }; - dc_msg::dc_msg_get_summary(msg, chat) + let lot = dc_msg::dc_msg_get_summary(msg, chat); + Box::into_raw(Box::new(lot)) } #[no_mangle] @@ -1789,67 +1792,74 @@ pub unsafe extern "C" fn dc_contact_is_verified(contact: *mut dc_contact_t) -> l // dc_lot_t #[no_mangle] -pub type dc_lot_t = dc_lot::dc_lot_t; +pub type dc_lot_t = dc_lot::Lot; #[no_mangle] -pub unsafe extern "C" fn dc_lot_new() -> *mut dc_lot::dc_lot_t { - dc_lot::dc_lot_new() +pub unsafe extern "C" fn dc_lot_new() -> *mut dc_lot_t { + Box::into_raw(Box::new(dc_lot::Lot::new())) } #[no_mangle] -pub unsafe extern "C" fn dc_lot_empty(lot: *mut dc_lot::dc_lot_t) { +pub unsafe extern "C" fn dc_lot_empty(lot: *mut dc_lot_t) { assert!(!lot.is_null()); - dc_lot::dc_lot_empty(lot) + let _lot = Box::from_raw(lot); + *lot = dc_lot::Lot::new(); } #[no_mangle] -pub unsafe extern "C" fn dc_lot_unref(lot: *mut dc_lot::dc_lot_t) { +pub unsafe extern "C" fn dc_lot_unref(lot: *mut dc_lot_t) { assert!(!lot.is_null()); - dc_lot::dc_lot_unref(lot) + Box::from_raw(lot); } #[no_mangle] -pub unsafe extern "C" fn dc_lot_get_text1(lot: *mut dc_lot::dc_lot_t) -> *mut libc::c_char { +pub unsafe extern "C" fn dc_lot_get_text1(lot: *mut dc_lot_t) -> *mut libc::c_char { assert!(!lot.is_null()); - dc_lot::dc_lot_get_text1(lot) + let lot = &*lot; + lot.get_text1() } #[no_mangle] -pub unsafe extern "C" fn dc_lot_get_text2(lot: *mut dc_lot::dc_lot_t) -> *mut libc::c_char { +pub unsafe extern "C" fn dc_lot_get_text2(lot: *mut dc_lot_t) -> *mut libc::c_char { assert!(!lot.is_null()); - dc_lot::dc_lot_get_text2(lot) + let lot = &*lot; + lot.get_text2() } #[no_mangle] -pub unsafe extern "C" fn dc_lot_get_text1_meaning(lot: *mut dc_lot::dc_lot_t) -> libc::c_int { +pub unsafe extern "C" fn dc_lot_get_text1_meaning(lot: *mut dc_lot_t) -> libc::c_int { assert!(!lot.is_null()); - dc_lot::dc_lot_get_text1_meaning(lot) + let lot = &*lot; + lot.get_text1_meaning() } #[no_mangle] -pub unsafe extern "C" fn dc_lot_get_state(lot: *mut dc_lot::dc_lot_t) -> libc::c_int { +pub unsafe extern "C" fn dc_lot_get_state(lot: *mut dc_lot_t) -> libc::c_int { assert!(!lot.is_null()); - dc_lot::dc_lot_get_state(lot) + let lot = &*lot; + lot.get_state() } #[no_mangle] -pub unsafe extern "C" fn dc_lot_get_id(lot: *mut dc_lot::dc_lot_t) -> u32 { +pub unsafe extern "C" fn dc_lot_get_id(lot: *mut dc_lot_t) -> u32 { assert!(!lot.is_null()); - dc_lot::dc_lot_get_id(lot) + let lot = &*lot; + lot.get_id() } #[no_mangle] -pub unsafe extern "C" fn dc_lot_get_timestamp(lot: *mut dc_lot::dc_lot_t) -> i64 { +pub unsafe extern "C" fn dc_lot_get_timestamp(lot: *mut dc_lot_t) -> i64 { assert!(!lot.is_null()); - dc_lot::dc_lot_get_timestamp(lot) + let lot = &*lot; + lot.get_timestamp() } #[no_mangle] diff --git a/examples/repl/cmdline.rs b/examples/repl/cmdline.rs index 21416b7bd..d391bbf0c 100644 --- a/examples/repl/cmdline.rs +++ b/examples/repl/cmdline.rs @@ -12,7 +12,6 @@ use deltachat::dc_configure::*; use deltachat::dc_imex::*; use deltachat::dc_job::*; use deltachat::dc_location::*; -use deltachat::dc_lot::*; use deltachat::dc_msg::*; use deltachat::dc_qr::*; use deltachat::dc_receive_imf::*; @@ -621,7 +620,7 @@ pub unsafe fn dc_cmdline(context: &Context, line: &str) -> Result<(), failure::E let statestr = if chat.is_archived() { " [Archived]" } else { - match dc_lot_get_state(lot) { + match lot.get_state() { 20 => " o", 26 => " √", 28 => " √√", @@ -629,9 +628,9 @@ pub unsafe fn dc_cmdline(context: &Context, line: &str) -> Result<(), failure::E _ => "", } }; - let timestr = dc_timestamp_to_str(dc_lot_get_timestamp(lot)); - let text1 = dc_lot_get_text1(lot); - let text2 = dc_lot_get_text2(lot); + let timestr = dc_timestamp_to_str(lot.get_timestamp()); + let text1 = lot.get_text1(); + let text2 = lot.get_text2(); info!( context, 0, @@ -649,7 +648,6 @@ pub unsafe fn dc_cmdline(context: &Context, line: &str) -> Result<(), failure::E ); free(text1 as *mut libc::c_void); free(text2 as *mut libc::c_void); - dc_lot_unref(lot); info!( context, 0, "================================================================================" @@ -1054,12 +1052,11 @@ pub unsafe fn dc_cmdline(context: &Context, line: &str) -> Result<(), failure::E let res = dc_check_qr(context, arg1_c); println!( "state={}, id={}, text1={}, text2={}", - (*res).state as libc::c_int, - (*res).id, - to_string((*res).text1), - to_string((*res).text2) + res.get_state(), + res.get_id(), + to_string(res.get_text1()), + to_string(res.get_text2()) ); - dc_lot_unref(res); } "event" => { ensure!(!arg1.is_empty(), "Argument missing."); diff --git a/examples/simple.rs b/examples/simple.rs index 2a52d6041..32a9203f3 100644 --- a/examples/simple.rs +++ b/examples/simple.rs @@ -16,7 +16,6 @@ use deltachat::dc_job::{ dc_perform_imap_fetch, dc_perform_imap_idle, dc_perform_imap_jobs, dc_perform_smtp_idle, dc_perform_smtp_jobs, }; -use deltachat::dc_lot::*; extern "C" fn cb(_ctx: &Context, event: Event, data1: usize, data2: usize) -> usize { println!("[{:?}]", event); @@ -104,8 +103,8 @@ fn main() { for i in 0..chats.len() { let summary = chats.get_summary(0, None); - let text1 = dc_lot_get_text1(summary); - let text2 = dc_lot_get_text2(summary); + let text1 = summary.get_text1(); + let text2 = summary.get_text2(); let text1_s = if !text1.is_null() { Some(CStr::from_ptr(text1)) @@ -118,7 +117,6 @@ fn main() { None }; println!("chat: {} - {:?} - {:?}", i, text1_s, text2_s,); - dc_lot_unref(summary); } thread::sleep(duration); diff --git a/src/chatlist.rs b/src/chatlist.rs index 4fc1c308c..192c918f5 100644 --- a/src/chatlist.rs +++ b/src/chatlist.rs @@ -2,7 +2,7 @@ use crate::chat::*; use crate::constants::*; use crate::contact::*; use crate::context::*; -use crate::dc_lot::*; +use crate::dc_lot::Lot; use crate::dc_msg::*; use crate::dc_tools::*; use crate::error::Result; @@ -249,15 +249,15 @@ impl<'a> Chatlist<'a> { /// - dc_lot_t::timestamp: the timestamp of the message. 0 if not applicable. /// - dc_lot_t::state: The state of the message as one of the DC_STATE_* constants (see #dc_msg_get_state()). // 0 if not applicable. - pub unsafe fn get_summary(&self, index: usize, chat: Option<&Chat<'a>>) -> *mut dc_lot_t { + pub unsafe fn get_summary(&self, index: usize, chat: Option<&Chat<'a>>) -> Lot { // The summary is created by the chat, not by the last message. // This is because we may want to display drafts here or stuff as // "is typing". // Also, sth. as "No messages" would not work if the summary comes from a message. - let mut ret = dc_lot_new(); + let mut ret = Lot::new(); if index >= self.ids.len() { - (*ret).text2 = "ErrBadChatlistIndex".strdup(); + ret.text2 = "ErrBadChatlistIndex".strdup(); return ret; } @@ -291,11 +291,11 @@ impl<'a> Chatlist<'a> { }; if chat.id == DC_CHAT_ID_ARCHIVED_LINK as u32 { - (*ret).text2 = dc_strdup(ptr::null()) + ret.text2 = dc_strdup(ptr::null()) } else if lastmsg.is_null() || (*lastmsg).from_id == DC_CONTACT_ID_UNDEFINED as u32 { - (*ret).text2 = self.context.stock_str(StockMessage::NoMessages).strdup(); + ret.text2 = self.context.stock_str(StockMessage::NoMessages).strdup(); } else { - dc_lot_fill(ret, lastmsg, chat, lastcontact.as_ref(), self.context); + ret.fill(lastmsg, chat, lastcontact.as_ref(), self.context); } dc_msg_unref(lastmsg); diff --git a/src/context.rs b/src/context.rs index 8732c559b..6f9aaaf69 100644 --- a/src/context.rs +++ b/src/context.rs @@ -6,7 +6,7 @@ use crate::contact::*; use crate::dc_job::*; use crate::dc_jobthread::*; use crate::dc_loginparam::*; -use crate::dc_lot::dc_lot_t; +use crate::dc_lot::Lot; use crate::dc_move::*; use crate::dc_msg::*; use crate::dc_receive_imf::*; @@ -99,21 +99,11 @@ impl Default for RunningState { } } -#[derive(Debug, PartialEq, Eq)] +#[derive(Default)] pub struct BobStatus { pub expects: i32, pub status: i32, - pub qr_scan: *mut dc_lot_t, -} - -impl Default for BobStatus { - fn default() -> Self { - BobStatus { - expects: 0, - status: 0, - qr_scan: std::ptr::null_mut(), - } - } + pub qr_scan: Option, } #[derive(Default, Debug)] diff --git a/src/dc_lot.rs b/src/dc_lot.rs index 134a6bcf6..15a5976ce 100644 --- a/src/dc_lot.rs +++ b/src/dc_lot.rs @@ -5,174 +5,132 @@ use crate::context::Context; use crate::dc_msg::*; use crate::dc_tools::*; use crate::stock::StockMessage; -use crate::types::*; use crate::x::*; -/* * Structure behind dc_lot_t */ -#[derive(Copy, Clone)] -#[repr(C)] -pub struct dc_lot_t { - pub text1_meaning: libc::c_int, - pub text1: *mut libc::c_char, - pub text2: *mut libc::c_char, - pub timestamp: i64, - pub state: libc::c_int, - pub id: uint32_t, - pub fingerprint: *mut libc::c_char, - pub invitenumber: *mut libc::c_char, - pub auth: *mut libc::c_char, +/// An object containing a set of values. +/// The meaning of the values is defined by the function returning the object. +/// Lot objects are created +/// eg. by chatlist.get_summary() or dc_msg_get_summary(). +/// +/// _Lot_ is used in the meaning _heap_ here. +#[derive(Clone)] +pub struct Lot { + pub(crate) text1_meaning: i32, + pub(crate) text1: *mut libc::c_char, + pub(crate) text2: *mut libc::c_char, + pub(crate) timestamp: i64, + pub(crate) state: i32, + pub(crate) id: u32, + pub(crate) fingerprint: *mut libc::c_char, + pub(crate) invitenumber: *mut libc::c_char, + pub(crate) auth: *mut libc::c_char, } -/* * - * @class dc_lot_t - * - * An object containing a set of values. - * The meaning of the values is defined by the function returning the object. - * Lot objects are created - * eg. by chatlist.get_summary() or dc_msg_get_summary(). - * - * NB: _Lot_ is used in the meaning _heap_ here. - */ -pub unsafe fn dc_lot_new() -> *mut dc_lot_t { - let mut lot: *mut dc_lot_t; - lot = calloc(1, ::std::mem::size_of::()) as *mut dc_lot_t; - assert!(!lot.is_null()); - - (*lot).text1_meaning = 0i32; - - lot -} - -pub unsafe fn dc_lot_empty(mut lot: *mut dc_lot_t) { - if lot.is_null() { - return; - } - free((*lot).text1 as *mut libc::c_void); - (*lot).text1 = 0 as *mut libc::c_char; - (*lot).text1_meaning = 0i32; - free((*lot).text2 as *mut libc::c_void); - (*lot).text2 = 0 as *mut libc::c_char; - free((*lot).fingerprint as *mut libc::c_void); - (*lot).fingerprint = 0 as *mut libc::c_char; - free((*lot).invitenumber as *mut libc::c_void); - (*lot).invitenumber = 0 as *mut libc::c_char; - free((*lot).auth as *mut libc::c_void); - (*lot).auth = 0 as *mut libc::c_char; - (*lot).timestamp = 0; - (*lot).state = 0i32; - (*lot).id = 0i32 as uint32_t; -} - -pub unsafe fn dc_lot_unref(set: *mut dc_lot_t) { - if set.is_null() { - return; - } - dc_lot_empty(set); - free(set as *mut libc::c_void); -} - -pub unsafe fn dc_lot_get_text1(lot: *const dc_lot_t) -> *mut libc::c_char { - if lot.is_null() { - return 0 as *mut libc::c_char; - } - - dc_strdup_keep_null((*lot).text1) -} - -pub unsafe fn dc_lot_get_text2(lot: *const dc_lot_t) -> *mut libc::c_char { - if lot.is_null() { - return 0 as *mut libc::c_char; - } - - dc_strdup_keep_null((*lot).text2) -} - -pub unsafe fn dc_lot_get_text1_meaning(lot: *const dc_lot_t) -> libc::c_int { - if lot.is_null() { - return 0i32; - } - - (*lot).text1_meaning -} - -pub unsafe fn dc_lot_get_state(lot: *const dc_lot_t) -> libc::c_int { - if lot.is_null() { - return 0i32; - } - - (*lot).state -} - -pub unsafe fn dc_lot_get_id(lot: *const dc_lot_t) -> uint32_t { - if lot.is_null() { - return 0i32 as uint32_t; - } - - (*lot).id -} - -pub unsafe fn dc_lot_get_timestamp(lot: *const dc_lot_t) -> i64 { - if lot.is_null() { - return 0; - } - - (*lot).timestamp -} - -/* library-internal */ -/* in practice, the user additionally cuts the string himself pixel-accurate */ -pub unsafe fn dc_lot_fill( - mut lot: *mut dc_lot_t, - msg: *mut dc_msg_t, - chat: &Chat, - contact: Option<&Contact>, - context: &Context, -) { - if lot.is_null() || msg.is_null() { - return; - } - if (*msg).state == 19i32 { - (*lot).text1 = context.stock_str(StockMessage::Draft).strdup(); - (*lot).text1_meaning = 1i32 - } else if (*msg).from_id == 1i32 as libc::c_uint { - if 0 != dc_msg_is_info(msg) || chat.is_self_talk() { - (*lot).text1 = 0 as *mut libc::c_char; - (*lot).text1_meaning = 0i32 - } else { - (*lot).text1 = context.stock_str(StockMessage::SelfMsg).strdup(); - (*lot).text1_meaning = 3i32 +impl Lot { + pub fn new() -> Self { + Lot { + text1_meaning: 0, + text1: std::ptr::null_mut(), + text2: std::ptr::null_mut(), + timestamp: 0, + state: 0, + id: 0, + fingerprint: std::ptr::null_mut(), + invitenumber: std::ptr::null_mut(), + auth: std::ptr::null_mut(), } - } else if chat.typ == Chattype::Group || chat.typ == Chattype::VerifiedGroup { - if 0 != dc_msg_is_info(msg) || contact.is_none() { - (*lot).text1 = 0 as *mut libc::c_char; - (*lot).text1_meaning = 0i32 - } else { - if chat.id == 1 { - if let Some(contact) = contact { - (*lot).text1 = contact.get_display_name().strdup(); - } else { - (*lot).text1 = std::ptr::null_mut(); - } + } + pub unsafe fn get_text1(&self) -> *mut libc::c_char { + dc_strdup_keep_null(self.text1) + } + + pub unsafe fn get_text2(&self) -> *mut libc::c_char { + dc_strdup_keep_null(self.text2) + } + + pub fn get_text1_meaning(&self) -> i32 { + self.text1_meaning + } + + pub fn get_state(&self) -> i32 { + self.state + } + + pub fn get_id(&self) -> u32 { + self.id + } + + pub fn get_timestamp(&self) -> i64 { + self.timestamp + } + + /* library-internal */ + /* in practice, the user additionally cuts the string himself pixel-accurate */ + pub unsafe fn fill( + &mut self, + msg: *mut dc_msg_t, + chat: &Chat, + contact: Option<&Contact>, + context: &Context, + ) { + if msg.is_null() { + return; + } + if (*msg).state == 19i32 { + self.text1 = context.stock_str(StockMessage::Draft).strdup(); + self.text1_meaning = 1i32 + } else if (*msg).from_id == 1i32 as libc::c_uint { + if 0 != dc_msg_is_info(msg) || chat.is_self_talk() { + self.text1 = 0 as *mut libc::c_char; + self.text1_meaning = 0i32 } else { - if let Some(contact) = contact { - (*lot).text1 = contact.get_first_name().strdup(); - } else { - (*lot).text1 = std::ptr::null_mut(); - } + self.text1 = context.stock_str(StockMessage::SelfMsg).strdup(); + self.text1_meaning = 3i32 } - (*lot).text1_meaning = 2i32; + } else if chat.typ == Chattype::Group || chat.typ == Chattype::VerifiedGroup { + if 0 != dc_msg_is_info(msg) || contact.is_none() { + self.text1 = 0 as *mut libc::c_char; + self.text1_meaning = 0i32 + } else { + if chat.id == 1 { + if let Some(contact) = contact { + self.text1 = contact.get_display_name().strdup(); + } else { + self.text1 = std::ptr::null_mut(); + } + } else { + if let Some(contact) = contact { + self.text1 = contact.get_first_name().strdup(); + } else { + self.text1 = std::ptr::null_mut(); + } + } + self.text1_meaning = 2i32; + } + } + + self.text2 = dc_msg_get_summarytext_by_raw( + (*msg).type_0, + (*msg).text.as_ref(), + &mut (*msg).param, + 160, + context, + ) + .strdup(); + + self.timestamp = dc_msg_get_timestamp(msg); + self.state = (*msg).state; + } +} + +impl Drop for Lot { + fn drop(&mut self) { + unsafe { + free(self.text1.cast()); + free(self.text2.cast()); + free(self.fingerprint.cast()); + free(self.invitenumber.cast()); + free(self.auth.cast()); } } - - (*lot).text2 = dc_msg_get_summarytext_by_raw( - (*msg).type_0, - (*msg).text.as_ref(), - &mut (*msg).param, - 160, - context, - ) - .strdup(); - - (*lot).timestamp = dc_msg_get_timestamp(msg); - (*lot).state = (*msg).state; } diff --git a/src/dc_msg.rs b/src/dc_msg.rs index 20713f170..dceecdc98 100644 --- a/src/dc_msg.rs +++ b/src/dc_msg.rs @@ -1,13 +1,15 @@ use std::ffi::CString; use std::path::Path; +use std::ptr; + +use phf::phf_map; use crate::chat::{self, Chat}; use crate::constants::*; use crate::contact::*; use crate::context::*; use crate::dc_job::*; -use crate::dc_lot::dc_lot_t; -use crate::dc_lot::*; +use crate::dc_lot::Lot; use crate::dc_tools::*; use crate::param::*; use crate::pgp::*; @@ -15,8 +17,6 @@ use crate::sql; use crate::stock::StockMessage; use crate::types::*; use crate::x::*; -use phf::phf_map; -use std::ptr; /* * the structure behind dc_msg_t */ #[derive(Clone)] @@ -741,11 +741,8 @@ pub unsafe fn dc_msg_get_showpadlock(msg: *const dc_msg_t) -> libc::c_int { 0 } -pub unsafe fn dc_msg_get_summary<'a>( - msg: *mut dc_msg_t<'a>, - chat: Option<&Chat<'a>>, -) -> *mut dc_lot_t { - let ret = dc_lot_new(); +pub unsafe fn dc_msg_get_summary<'a>(msg: *mut dc_msg_t<'a>, chat: Option<&Chat<'a>>) -> Lot { + let mut ret = Lot::new(); if msg.is_null() { return ret; @@ -771,7 +768,7 @@ pub unsafe fn dc_msg_get_summary<'a>( None }; - dc_lot_fill(ret, msg, chat, contact.as_ref(), (*msg).context); + ret.fill(msg, chat, contact.as_ref(), (*msg).context); ret } diff --git a/src/dc_qr.rs b/src/dc_qr.rs index 82951c021..048da3f4d 100644 --- a/src/dc_qr.rs +++ b/src/dc_qr.rs @@ -4,7 +4,7 @@ use crate::chat; use crate::constants::Blocked; use crate::contact::*; use crate::context::Context; -use crate::dc_lot::*; +use crate::dc_lot::Lot; use crate::dc_strencode::*; use crate::dc_tools::*; use crate::key::*; @@ -23,7 +23,7 @@ use crate::x::*; // text1=text // text1=URL // text1=error string -pub unsafe fn dc_check_qr(context: &Context, qr: *const libc::c_char) -> *mut dc_lot_t { +pub unsafe fn dc_check_qr(context: &Context, qr: *const libc::c_char) -> Lot { let mut ok_to_continue = true; let mut payload: *mut libc::c_char = 0 as *mut libc::c_char; // must be normalized, if set @@ -33,12 +33,12 @@ pub unsafe fn dc_check_qr(context: &Context, qr: *const libc::c_char) -> *mut dc let mut name: *mut libc::c_char = 0 as *mut libc::c_char; let mut invitenumber: *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 = Lot::new(); let mut chat_id: uint32_t = 0i32 as uint32_t; let mut device_msg = "".to_string(); 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; - (*qr_parsed).state = 0i32; + qr_parsed.state = 0i32; if !qr.is_null() { info!(context, 0, "Scanned QR code: {}", as_str(qr),); /* split parameters from the qr code @@ -136,8 +136,8 @@ pub unsafe fn dc_check_qr(context: &Context, qr: *const libc::c_char) -> *mut dc *semicolon = 0i32 as libc::c_char } } else { - (*qr_parsed).state = 400i32; - (*qr_parsed).text1 = + qr_parsed.state = 400i32; + qr_parsed.text1 = dc_strdup(b"Bad e-mail address.\x00" as *const u8 as *const libc::c_char); ok_to_continue = false; } @@ -201,16 +201,16 @@ pub unsafe fn dc_check_qr(context: &Context, qr: *const libc::c_char) -> *mut dc free(addr as *mut libc::c_void); addr = temp; if !may_be_valid_addr(as_str(addr)) { - (*qr_parsed).state = 400i32; - (*qr_parsed).text1 = + qr_parsed.state = 400i32; + qr_parsed.text1 = dc_strdup(b"Bad e-mail address.\x00" as *const u8 as *const libc::c_char); ok_to_continue = false; } } } if ok_to_continue && !fingerprint.is_null() && strlen(fingerprint) != 40 { - (*qr_parsed).state = 400i32; - (*qr_parsed).text1 = dc_strdup( + qr_parsed.state = 400i32; + qr_parsed.text1 = dc_strdup( b"Bad fingerprint length in QR code.\x00" as *const u8 as *const libc::c_char, ); ok_to_continue = false; @@ -221,37 +221,37 @@ pub unsafe fn dc_check_qr(context: &Context, qr: *const libc::c_char) -> *mut dc Peerstate::from_fingerprint(context, &context.sql, as_str(fingerprint)); if addr.is_null() || invitenumber.is_null() || auth.is_null() { if let Some(peerstate) = peerstate { - (*qr_parsed).state = 210i32; + qr_parsed.state = 210i32; let addr = peerstate .addr .as_ref() .map(|s| s.as_str()) .unwrap_or_else(|| ""); - (*qr_parsed).id = + qr_parsed.id = Contact::add_or_lookup(context, "", addr, Origin::UnhandledQrScan) .map(|(id, _)| id) .unwrap_or_default(); let (id, _) = chat::create_or_lookup_by_contact_id( context, - (*qr_parsed).id, + qr_parsed.id, Blocked::Deaddrop, ) .unwrap_or_default(); chat_id = id; device_msg = format!("{} verified.", peerstate.addr.unwrap_or_default()); } else { - (*qr_parsed).text1 = dc_format_fingerprint_c(fingerprint); - (*qr_parsed).state = 230i32; + qr_parsed.text1 = dc_format_fingerprint_c(fingerprint); + qr_parsed.state = 230i32; } } else { if !grpid.is_null() && !grpname.is_null() { - (*qr_parsed).state = 202i32; - (*qr_parsed).text1 = dc_strdup(grpname); - (*qr_parsed).text2 = dc_strdup(grpid) + qr_parsed.state = 202i32; + qr_parsed.text1 = dc_strdup(grpname); + qr_parsed.text2 = dc_strdup(grpid) } else { - (*qr_parsed).state = 200i32 + qr_parsed.state = 200i32 } - (*qr_parsed).id = Contact::add_or_lookup( + qr_parsed.id = Contact::add_or_lookup( context, as_str(name), as_str(addr), @@ -259,13 +259,13 @@ pub unsafe fn dc_check_qr(context: &Context, qr: *const libc::c_char) -> *mut dc ) .map(|(id, _)| id) .unwrap_or_default(); - (*qr_parsed).fingerprint = dc_strdup(fingerprint); - (*qr_parsed).invitenumber = dc_strdup(invitenumber); - (*qr_parsed).auth = dc_strdup(auth) + qr_parsed.fingerprint = dc_strdup(fingerprint); + qr_parsed.invitenumber = dc_strdup(invitenumber); + qr_parsed.auth = dc_strdup(auth) } } else if !addr.is_null() { - (*qr_parsed).state = 320i32; - (*qr_parsed).id = Contact::add_or_lookup( + qr_parsed.state = 320i32; + qr_parsed.id = Contact::add_or_lookup( context, as_str(name), as_str(addr), @@ -278,11 +278,11 @@ pub unsafe fn dc_check_qr(context: &Context, qr: *const libc::c_char) -> *mut dc || strstr(qr, b"https://\x00" as *const u8 as *const libc::c_char) == qr as *mut libc::c_char { - (*qr_parsed).state = 332i32; - (*qr_parsed).text1 = dc_strdup(qr) + qr_parsed.state = 332i32; + qr_parsed.text1 = dc_strdup(qr) } else { - (*qr_parsed).state = 330i32; - (*qr_parsed).text1 = dc_strdup(qr) + qr_parsed.state = 330i32; + qr_parsed.text1 = dc_strdup(qr) } if !device_msg.is_empty() { chat::add_device_msg(context, chat_id, device_msg); diff --git a/src/dc_securejoin.rs b/src/dc_securejoin.rs index 11a162e2b..fd83d0ad7 100644 --- a/src/dc_securejoin.rs +++ b/src/dc_securejoin.rs @@ -8,7 +8,6 @@ use crate::contact::*; use crate::context::Context; use crate::dc_configure::*; use crate::dc_e2ee::*; -use crate::dc_lot::*; use crate::dc_mimeparser::*; use crate::dc_msg::*; use crate::dc_qr::*; @@ -137,17 +136,17 @@ pub unsafe fn dc_join_securejoin(context: &Context, qr: *const libc::c_char) -> let ongoing_allocated: libc::c_int; let mut contact_chat_id: uint32_t = 0i32 as uint32_t; let mut join_vg: libc::c_int = 0i32; - let mut qr_scan: *mut dc_lot_t = 0 as *mut dc_lot_t; + info!(context, 0, "Requesting secure-join ...",); dc_ensure_secret_key_exists(context).ok(); ongoing_allocated = dc_alloc_ongoing(context); + if !(ongoing_allocated == 0i32) { - qr_scan = dc_check_qr(context, qr); - if qr_scan.is_null() || (*qr_scan).state != 200i32 && (*qr_scan).state != 202i32 { + let qr_scan = dc_check_qr(context, qr); + if qr_scan.state != 200i32 && qr_scan.state != 202i32 { error!(context, 0, "Unknown QR code.",); } else { - contact_chat_id = - chat::create_by_contact_id(context, (*qr_scan).id).unwrap_or_default(); + contact_chat_id = chat::create_by_contact_id(context, qr_scan.id).unwrap_or_default(); if contact_chat_id == 0i32 as libc::c_uint { error!(context, 0, "Unknown contact.",); } else if !(context @@ -157,17 +156,26 @@ pub unsafe fn dc_join_securejoin(context: &Context, qr: *const libc::c_char) -> .unwrap() .shall_stop_ongoing) { - join_vg = ((*qr_scan).state == 202i32) as libc::c_int; + join_vg = (qr_scan.state == 202i32) as libc::c_int; { - let bob_a = context.bob.clone(); - let mut bob = bob_a.write().unwrap(); + let mut bob = context.bob.write().unwrap(); bob.status = 0; - bob.qr_scan = qr_scan; + bob.qr_scan = Some(qr_scan); } - if 0 != fingerprint_equals_sender(context, (*qr_scan).fingerprint, contact_chat_id) - { + if 0 != fingerprint_equals_sender( + context, + context + .bob + .read() + .unwrap() + .qr_scan + .as_ref() + .unwrap() + .fingerprint, + contact_chat_id, + ) { info!(context, 0, "Taking protocol shortcut."); - context.bob.clone().write().unwrap().expects = 6; + context.bob.write().unwrap().expects = 6; context.call_cb( Event::SECUREJOIN_JOINER_PROGRESS, chat_id_2_contact_id(context, contact_chat_id) as uintptr_t, @@ -182,17 +190,17 @@ pub unsafe fn dc_join_securejoin(context: &Context, qr: *const libc::c_char) -> } else { b"vc-request-with-auth\x00" as *const u8 as *const libc::c_char }, - (*qr_scan).auth, + context.bob.read().unwrap().qr_scan.as_ref().unwrap().auth, own_fingerprint, if 0 != join_vg { - as_str((*qr_scan).text2) + as_str(context.bob.read().unwrap().qr_scan.as_ref().unwrap().text2) } else { "" }, ); free(own_fingerprint as *mut libc::c_void); } else { - context.bob.clone().write().unwrap().expects = 2; + context.bob.write().unwrap().expects = 2; send_handshake_msg( context, contact_chat_id, @@ -201,7 +209,14 @@ pub unsafe fn dc_join_securejoin(context: &Context, qr: *const libc::c_char) -> } else { b"vc-request\x00" as *const u8 as *const libc::c_char }, - (*qr_scan).invitenumber, + context + .bob + .read() + .unwrap() + .qr_scan + .as_ref() + .unwrap() + .invitenumber, 0 as *const libc::c_char, "", ); @@ -220,15 +235,13 @@ pub unsafe fn dc_join_securejoin(context: &Context, qr: *const libc::c_char) -> } } } - let bob_a = context.bob.clone(); - let mut bob = bob_a.write().unwrap(); - + let mut bob = context.bob.write().unwrap(); bob.expects = 0; if bob.status == 1 { if 0 != join_vg { ret_chat_id = chat::get_chat_id_by_grpid( context, - to_string((*qr_scan).text2), + to_string(bob.qr_scan.as_ref().unwrap().text2), None, 0 as *mut libc::c_int, ) as libc::c_int @@ -236,9 +249,9 @@ pub unsafe fn dc_join_securejoin(context: &Context, qr: *const libc::c_char) -> ret_chat_id = contact_chat_id as libc::c_int } } - bob.qr_scan = std::ptr::null_mut(); - dc_lot_unref(qr_scan); + bob.qr_scan = None; + if 0 != ongoing_allocated { dc_free_ongoing(context); } @@ -414,10 +427,9 @@ pub unsafe fn dc_handle_securejoin_handshake( ) == 0i32 { let cond = { - let bob_a = context.bob.clone(); - let bob = bob_a.read().unwrap(); - let scan = bob.qr_scan; - scan.is_null() || bob.expects != 2 || 0 != join_vg && (*scan).state != 202 + let bob = context.bob.read().unwrap(); + let scan = bob.qr_scan.as_ref(); + scan.is_none() || bob.expects != 2 || 0 != join_vg && scan.unwrap().state != 202 }; if cond { @@ -426,11 +438,22 @@ pub unsafe fn dc_handle_securejoin_handshake( current_block = 4378276786830486580; } else { { - let scan = context.bob.clone().read().unwrap().qr_scan; - scanned_fingerprint_of_alice = dc_strdup((*scan).fingerprint); - auth = dc_strdup((*scan).auth); + scanned_fingerprint_of_alice = dc_strdup( + context + .bob + .read() + .unwrap() + .qr_scan + .as_ref() + .unwrap() + .fingerprint, + ); + auth = + dc_strdup(context.bob.read().unwrap().qr_scan.as_ref().unwrap().auth); if 0 != join_vg { - grpid = to_string((*scan).text2); + grpid = to_string( + context.bob.read().unwrap().qr_scan.as_ref().unwrap().text2, + ); } } if !encrypted_and_signed(mimeparser, scanned_fingerprint_of_alice) { @@ -468,7 +491,7 @@ pub unsafe fn dc_handle_securejoin_handshake( contact_id as uintptr_t, 400i32 as uintptr_t, ); - context.bob.clone().write().unwrap().expects = 6; + context.bob.write().unwrap().expects = 6; send_handshake_msg( context, @@ -619,13 +642,14 @@ pub unsafe fn dc_handle_securejoin_handshake( if 0 != join_vg { ret = 0x1i32 } - if context.bob.clone().read().unwrap().expects != 6 { + if context.bob.read().unwrap().expects != 6 { info!(context, 0, "Message belongs to a different handshake.",); current_block = 4378276786830486580; } else { let cond = { - let scan = context.bob.clone().read().unwrap().qr_scan; - scan.is_null() || 0 != join_vg && (*scan).state != 202 + let bob = context.bob.read().unwrap(); + let scan = bob.qr_scan.as_ref(); + scan.is_none() || 0 != join_vg && scan.unwrap().state != 202 }; if cond { warn!( @@ -635,10 +659,20 @@ pub unsafe fn dc_handle_securejoin_handshake( current_block = 4378276786830486580; } else { { - let scan = context.bob.clone().read().unwrap().qr_scan; - scanned_fingerprint_of_alice = dc_strdup((*scan).fingerprint); + scanned_fingerprint_of_alice = dc_strdup( + context + .bob + .read() + .unwrap() + .qr_scan + .as_ref() + .unwrap() + .fingerprint, + ); if 0 != join_vg { - grpid = to_string((*scan).text2); + grpid = to_string( + context.bob.read().unwrap().qr_scan.as_ref().unwrap().text2, + ); } } let mut vg_expect_encrypted: libc::c_int = 1i32; @@ -717,7 +751,7 @@ pub unsafe fn dc_handle_securejoin_handshake( 4378276786830486580 => {} _ => { secure_connection_established(context, contact_chat_id); - context.bob.clone().write().unwrap().expects = 0; + context.bob.write().unwrap().expects = 0; if 0 != join_vg { send_handshake_msg( context, @@ -790,7 +824,7 @@ pub unsafe fn dc_handle_securejoin_handshake( } unsafe fn end_bobs_joining(context: &Context, status: libc::c_int) { - context.bob.clone().write().unwrap().status = status; + context.bob.write().unwrap().status = status; dc_stop_ongoing_process(context); } diff --git a/tests/stress.rs b/tests/stress.rs index 3ab927d14..22607bd1a 100644 --- a/tests/stress.rs +++ b/tests/stress.rs @@ -13,7 +13,6 @@ use deltachat::contact::*; use deltachat::context::*; use deltachat::dc_configure::*; use deltachat::dc_imex::*; -use deltachat::dc_lot::*; use deltachat::dc_mimeparser::*; use deltachat::dc_qr::*; use deltachat::dc_securejoin::*; @@ -455,20 +454,18 @@ unsafe fn stress_functions(context: &Context) { 3, ) == 0i32) ); - let mut res: *mut dc_lot_t = dc_check_qr(context, qr); - assert!(res.is_null()); - assert!(!((*res).state == 200i32 || (*res).state == 220i32 || (*res).state == 230i32)); + let mut res = dc_check_qr(context, qr); + assert!( + !(res.get_state() == 200i32 || res.get_state() == 220i32 || res.get_state() == 230i32) + ); - dc_lot_unref(res); free(qr as *mut libc::c_void); res = dc_check_qr(context, b"BEGIN:VCARD\nVERSION:3.0\nN:Last;First\nEMAIL;TYPE=INTERNET:stress@test.local\nEND:VCARD\x00" as *const u8 as *const libc::c_char); - assert!(res.is_null()); - assert!(!((*res).state == 320i32)); - assert!(!((*res).id != 0i32 as libc::c_uint)); - dc_lot_unref(res); + assert!(!(res.get_state() == 320i32)); + assert!(!(res.get_id() != 0i32 as libc::c_uint)); }; }