mirror of
https://github.com/chatmail/core.git
synced 2026-04-29 11:26:29 +03:00
refactor(lot): rust memory management
This commit is contained in:
committed by
holger krekel
parent
8c10aa287c
commit
b5c66dd52a
@@ -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);
|
||||
|
||||
@@ -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<Lot>,
|
||||
}
|
||||
|
||||
#[derive(Default, Debug)]
|
||||
|
||||
280
src/dc_lot.rs
280
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::<dc_lot_t>()) 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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
58
src/dc_qr.rs
58
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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user