mirror of
https://github.com/chatmail/core.git
synced 2026-05-22 16:26:31 +03:00
Fix bugs (#93)
* fix(repl): pass null pointer instead of empty string * fix(peerstate): ensure load and store to the db works
This commit is contained in:
committed by
Lars-Magnus Skog
parent
0d51c7dd2e
commit
d033667433
@@ -32,6 +32,8 @@ chrono = "0.4.6"
|
|||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
tempfile = "3.0"
|
tempfile = "3.0"
|
||||||
|
pretty_assertions = "0.6.1"
|
||||||
|
pretty_env_logger = "0.3.0"
|
||||||
|
|
||||||
[workspace]
|
[workspace]
|
||||||
members = [
|
members = [
|
||||||
|
|||||||
@@ -481,6 +481,11 @@ pub unsafe fn dc_cmdline(context: &Context, cmdline: &str) -> *mut libc::c_char
|
|||||||
|
|
||||||
let arg1 = args.next().unwrap_or_default();
|
let arg1 = args.next().unwrap_or_default();
|
||||||
let arg1_c = CString::new(arg1).unwrap();
|
let arg1_c = CString::new(arg1).unwrap();
|
||||||
|
let arg1_c_ptr = if arg1.is_empty() {
|
||||||
|
std::ptr::null()
|
||||||
|
} else {
|
||||||
|
arg1_c.as_ptr()
|
||||||
|
};
|
||||||
let arg2 = args.next().unwrap_or_default();
|
let arg2 = args.next().unwrap_or_default();
|
||||||
let arg2_c = CString::new(arg2).unwrap();
|
let arg2_c = CString::new(arg2).unwrap();
|
||||||
|
|
||||||
@@ -514,7 +519,7 @@ pub unsafe fn dc_cmdline(context: &Context, cmdline: &str) -> *mut libc::c_char
|
|||||||
} else if strcmp(cmd, b"open\x00" as *const u8 as *const libc::c_char) == 0i32 {
|
} else if strcmp(cmd, b"open\x00" as *const u8 as *const libc::c_char) == 0i32 {
|
||||||
if !arg1.is_empty() {
|
if !arg1.is_empty() {
|
||||||
dc_close(context);
|
dc_close(context);
|
||||||
ret = if 0 != dc_open(context, arg1_c.as_ptr(), 0 as *const libc::c_char) {
|
ret = if 0 != dc_open(context, arg1_c_ptr, 0 as *const libc::c_char) {
|
||||||
2i32 as *mut libc::c_char
|
2i32 as *mut libc::c_char
|
||||||
} else {
|
} else {
|
||||||
1i32 as *mut libc::c_char
|
1i32 as *mut libc::c_char
|
||||||
@@ -613,7 +618,7 @@ pub unsafe fn dc_cmdline(context: &Context, cmdline: &str) -> *mut libc::c_char
|
|||||||
) == 0i32
|
) == 0i32
|
||||||
{
|
{
|
||||||
if !arg1.is_empty() {
|
if !arg1.is_empty() {
|
||||||
dc_imex(context, 12i32, arg1_c.as_ptr(), 0 as *const libc::c_char);
|
dc_imex(context, 12i32, arg1_c_ptr, 0 as *const libc::c_char);
|
||||||
ret = 2i32 as *mut libc::c_char
|
ret = 2i32 as *mut libc::c_char
|
||||||
} else {
|
} else {
|
||||||
ret = dc_strdup(
|
ret = dc_strdup(
|
||||||
@@ -665,7 +670,7 @@ pub unsafe fn dc_cmdline(context: &Context, cmdline: &str) -> *mut libc::c_char
|
|||||||
free(file_name as *mut libc::c_void);
|
free(file_name as *mut libc::c_void);
|
||||||
free(setup_code_0 as *mut libc::c_void);
|
free(setup_code_0 as *mut libc::c_void);
|
||||||
} else if strcmp(cmd, b"poke\x00" as *const u8 as *const libc::c_char) == 0i32 {
|
} else if strcmp(cmd, b"poke\x00" as *const u8 as *const libc::c_char) == 0i32 {
|
||||||
ret = if 0 != poke_spec(context, arg1_c.as_ptr()) {
|
ret = if 0 != poke_spec(context, arg1_c_ptr) {
|
||||||
2i32 as *mut libc::c_char
|
2i32 as *mut libc::c_char
|
||||||
} else {
|
} else {
|
||||||
1i32 as *mut libc::c_char
|
1i32 as *mut libc::c_char
|
||||||
@@ -694,7 +699,7 @@ pub unsafe fn dc_cmdline(context: &Context, cmdline: &str) -> *mut libc::c_char
|
|||||||
ret = 2i32 as *mut libc::c_char
|
ret = 2i32 as *mut libc::c_char
|
||||||
} else if strcmp(cmd, b"set\x00" as *const u8 as *const libc::c_char) == 0i32 {
|
} else if strcmp(cmd, b"set\x00" as *const u8 as *const libc::c_char) == 0i32 {
|
||||||
if !arg1.is_empty() {
|
if !arg1.is_empty() {
|
||||||
ret = if 0 != dc_set_config(context, arg1_c.as_ptr(), arg2_c.as_ptr()) {
|
ret = if 0 != dc_set_config(context, arg1_c_ptr, arg2_c.as_ptr()) {
|
||||||
2i32 as *mut libc::c_char
|
2i32 as *mut libc::c_char
|
||||||
} else {
|
} else {
|
||||||
1i32 as *mut libc::c_char
|
1i32 as *mut libc::c_char
|
||||||
@@ -705,10 +710,10 @@ pub unsafe fn dc_cmdline(context: &Context, cmdline: &str) -> *mut libc::c_char
|
|||||||
}
|
}
|
||||||
} else if strcmp(cmd, b"get\x00" as *const u8 as *const libc::c_char) == 0i32 {
|
} else if strcmp(cmd, b"get\x00" as *const u8 as *const libc::c_char) == 0i32 {
|
||||||
if !arg1.is_empty() {
|
if !arg1.is_empty() {
|
||||||
let val: *mut libc::c_char = dc_get_config(context, arg1_c.as_ptr());
|
let val: *mut libc::c_char = dc_get_config(context, arg1_c_ptr);
|
||||||
ret = dc_mprintf(
|
ret = dc_mprintf(
|
||||||
b"%s=%s\x00" as *const u8 as *const libc::c_char,
|
b"%s=%s\x00" as *const u8 as *const libc::c_char,
|
||||||
arg1_c.as_ptr(),
|
arg1_c_ptr,
|
||||||
val,
|
val,
|
||||||
);
|
);
|
||||||
free(val as *mut libc::c_void);
|
free(val as *mut libc::c_void);
|
||||||
@@ -739,7 +744,7 @@ pub unsafe fn dc_cmdline(context: &Context, cmdline: &str) -> *mut libc::c_char
|
|||||||
};
|
};
|
||||||
|
|
||||||
let chatlist: *mut dc_chatlist_t =
|
let chatlist: *mut dc_chatlist_t =
|
||||||
dc_get_chatlist(context, listflags, arg1_c.as_ptr(), 0i32 as uint32_t);
|
dc_get_chatlist(context, listflags, arg1_c_ptr, 0i32 as uint32_t);
|
||||||
if !chatlist.is_null() {
|
if !chatlist.is_null() {
|
||||||
let mut i: libc::c_int;
|
let mut i: libc::c_int;
|
||||||
let cnt: libc::c_int = dc_chatlist_get_cnt(chatlist) as libc::c_int;
|
let cnt: libc::c_int = dc_chatlist_get_cnt(chatlist) as libc::c_int;
|
||||||
@@ -943,7 +948,7 @@ pub unsafe fn dc_cmdline(context: &Context, cmdline: &str) -> *mut libc::c_char
|
|||||||
} else if strcmp(cmd, b"creategroup\x00" as *const u8 as *const libc::c_char) == 0i32 {
|
} else if strcmp(cmd, b"creategroup\x00" as *const u8 as *const libc::c_char) == 0i32 {
|
||||||
if !arg1.is_empty() {
|
if !arg1.is_empty() {
|
||||||
let chat_id_1: libc::c_int =
|
let chat_id_1: libc::c_int =
|
||||||
dc_create_group_chat(context, 0i32, arg1_c.as_ptr()) as libc::c_int;
|
dc_create_group_chat(context, 0i32, arg1_c_ptr) as libc::c_int;
|
||||||
ret = if chat_id_1 != 0i32 {
|
ret = if chat_id_1 != 0i32 {
|
||||||
dc_mprintf(
|
dc_mprintf(
|
||||||
b"Group#%lu created successfully.\x00" as *const u8 as *const libc::c_char,
|
b"Group#%lu created successfully.\x00" as *const u8 as *const libc::c_char,
|
||||||
@@ -964,7 +969,7 @@ pub unsafe fn dc_cmdline(context: &Context, cmdline: &str) -> *mut libc::c_char
|
|||||||
{
|
{
|
||||||
if !arg1.is_empty() {
|
if !arg1.is_empty() {
|
||||||
let chat_id_2: libc::c_int =
|
let chat_id_2: libc::c_int =
|
||||||
dc_create_group_chat(context, 1i32, arg1_c.as_ptr()) as libc::c_int;
|
dc_create_group_chat(context, 1i32, arg1_c_ptr) as libc::c_int;
|
||||||
ret = if chat_id_2 != 0i32 {
|
ret = if chat_id_2 != 0i32 {
|
||||||
dc_mprintf(
|
dc_mprintf(
|
||||||
b"VerifiedGroup#%lu created successfully.\x00" as *const u8
|
b"VerifiedGroup#%lu created successfully.\x00" as *const u8
|
||||||
@@ -1034,7 +1039,7 @@ pub unsafe fn dc_cmdline(context: &Context, cmdline: &str) -> *mut libc::c_char
|
|||||||
} else if strcmp(cmd, b"groupname\x00" as *const u8 as *const libc::c_char) == 0i32 {
|
} else if strcmp(cmd, b"groupname\x00" as *const u8 as *const libc::c_char) == 0i32 {
|
||||||
if !sel_chat.is_null() {
|
if !sel_chat.is_null() {
|
||||||
if !arg1.is_empty() {
|
if !arg1.is_empty() {
|
||||||
ret = if 0 != dc_set_chat_name(context, dc_chat_get_id(sel_chat), arg1_c.as_ptr()) {
|
ret = if 0 != dc_set_chat_name(context, dc_chat_get_id(sel_chat), arg1_c_ptr) {
|
||||||
2i32 as *mut libc::c_char
|
2i32 as *mut libc::c_char
|
||||||
} else {
|
} else {
|
||||||
1i32 as *mut libc::c_char
|
1i32 as *mut libc::c_char
|
||||||
@@ -1054,7 +1059,7 @@ pub unsafe fn dc_cmdline(context: &Context, cmdline: &str) -> *mut libc::c_char
|
|||||||
context,
|
context,
|
||||||
dc_chat_get_id(sel_chat),
|
dc_chat_get_id(sel_chat),
|
||||||
if !arg1.is_empty() {
|
if !arg1.is_empty() {
|
||||||
arg1_c.as_ptr()
|
arg1_c_ptr
|
||||||
} else {
|
} else {
|
||||||
0 as *mut libc::c_char
|
0 as *mut libc::c_char
|
||||||
},
|
},
|
||||||
@@ -1179,7 +1184,7 @@ pub unsafe fn dc_cmdline(context: &Context, cmdline: &str) -> *mut libc::c_char
|
|||||||
} else if strcmp(cmd, b"send\x00" as *const u8 as *const libc::c_char) == 0i32 {
|
} else if strcmp(cmd, b"send\x00" as *const u8 as *const libc::c_char) == 0i32 {
|
||||||
if !sel_chat.is_null() {
|
if !sel_chat.is_null() {
|
||||||
if !arg1.is_empty() {
|
if !arg1.is_empty() {
|
||||||
if 0 != dc_send_text_msg(context, dc_chat_get_id(sel_chat), arg1_c.as_ptr()) {
|
if 0 != dc_send_text_msg(context, dc_chat_get_id(sel_chat), arg1_c_ptr) {
|
||||||
ret = dc_strdup(b"Message sent.\x00" as *const u8 as *const libc::c_char)
|
ret = dc_strdup(b"Message sent.\x00" as *const u8 as *const libc::c_char)
|
||||||
} else {
|
} else {
|
||||||
ret =
|
ret =
|
||||||
@@ -1220,7 +1225,7 @@ pub unsafe fn dc_cmdline(context: &Context, cmdline: &str) -> *mut libc::c_char
|
|||||||
60i32
|
60i32
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
dc_msg_set_file(msg_0, arg1_c.as_ptr(), 0 as *const libc::c_char);
|
dc_msg_set_file(msg_0, arg1_c_ptr, 0 as *const libc::c_char);
|
||||||
dc_msg_set_text(msg_0, arg2_c.as_ptr());
|
dc_msg_set_text(msg_0, arg2_c.as_ptr());
|
||||||
dc_send_msg(context, dc_chat_get_id(sel_chat), msg_0);
|
dc_send_msg(context, dc_chat_get_id(sel_chat), msg_0);
|
||||||
dc_msg_unref(msg_0);
|
dc_msg_unref(msg_0);
|
||||||
@@ -1240,7 +1245,7 @@ pub unsafe fn dc_cmdline(context: &Context, cmdline: &str) -> *mut libc::c_char
|
|||||||
} else {
|
} else {
|
||||||
0i32 as libc::c_uint
|
0i32 as libc::c_uint
|
||||||
},
|
},
|
||||||
arg1_c.as_ptr(),
|
arg1_c_ptr,
|
||||||
);
|
);
|
||||||
if !msglist_0.is_null() {
|
if !msglist_0.is_null() {
|
||||||
log_msglist(context, msglist_0);
|
log_msglist(context, msglist_0);
|
||||||
@@ -1259,7 +1264,7 @@ pub unsafe fn dc_cmdline(context: &Context, cmdline: &str) -> *mut libc::c_char
|
|||||||
if !sel_chat.is_null() {
|
if !sel_chat.is_null() {
|
||||||
if !arg1.is_empty() {
|
if !arg1.is_empty() {
|
||||||
let draft_0: *mut dc_msg_t = dc_msg_new(context, 10i32);
|
let draft_0: *mut dc_msg_t = dc_msg_new(context, 10i32);
|
||||||
dc_msg_set_text(draft_0, arg1_c.as_ptr());
|
dc_msg_set_text(draft_0, arg1_c_ptr);
|
||||||
dc_set_draft(context, dc_chat_get_id(sel_chat), draft_0);
|
dc_set_draft(context, dc_chat_get_id(sel_chat), draft_0);
|
||||||
dc_msg_unref(draft_0);
|
dc_msg_unref(draft_0);
|
||||||
ret = dc_strdup(b"Draft saved.\x00" as *const u8 as *const libc::c_char)
|
ret = dc_strdup(b"Draft saved.\x00" as *const u8 as *const libc::c_char)
|
||||||
@@ -1417,7 +1422,7 @@ pub unsafe fn dc_cmdline(context: &Context, cmdline: &str) -> *mut libc::c_char
|
|||||||
} else {
|
} else {
|
||||||
0x2i32
|
0x2i32
|
||||||
}) as uint32_t,
|
}) as uint32_t,
|
||||||
arg1_c.as_ptr(),
|
arg1_c_ptr,
|
||||||
);
|
);
|
||||||
if !contacts_0.is_null() {
|
if !contacts_0.is_null() {
|
||||||
log_contactlist(context, contacts_0);
|
log_contactlist(context, contacts_0);
|
||||||
@@ -1433,14 +1438,14 @@ pub unsafe fn dc_cmdline(context: &Context, cmdline: &str) -> *mut libc::c_char
|
|||||||
if !arg1.is_empty() && !arg2.is_empty() {
|
if !arg1.is_empty() && !arg2.is_empty() {
|
||||||
let book: *mut libc::c_char = dc_mprintf(
|
let book: *mut libc::c_char = dc_mprintf(
|
||||||
b"%s\n%s\x00" as *const u8 as *const libc::c_char,
|
b"%s\n%s\x00" as *const u8 as *const libc::c_char,
|
||||||
arg1_c.as_ptr(),
|
arg1_c_ptr,
|
||||||
arg2_c.as_ptr(),
|
arg2_c.as_ptr(),
|
||||||
);
|
);
|
||||||
dc_add_address_book(context, book);
|
dc_add_address_book(context, book);
|
||||||
ret = 2i32 as *mut libc::c_char;
|
ret = 2i32 as *mut libc::c_char;
|
||||||
free(book as *mut libc::c_void);
|
free(book as *mut libc::c_void);
|
||||||
} else if !arg1.is_empty() {
|
} else if !arg1.is_empty() {
|
||||||
ret = if 0 != dc_create_contact(context, 0 as *const libc::c_char, arg1_c.as_ptr()) {
|
ret = if 0 != dc_create_contact(context, 0 as *const libc::c_char, arg1_c_ptr) {
|
||||||
2i32 as *mut libc::c_char
|
2i32 as *mut libc::c_char
|
||||||
} else {
|
} else {
|
||||||
1i32 as *mut libc::c_char
|
1i32 as *mut libc::c_char
|
||||||
@@ -1544,7 +1549,7 @@ pub unsafe fn dc_cmdline(context: &Context, cmdline: &str) -> *mut libc::c_char
|
|||||||
}
|
}
|
||||||
} else if strcmp(cmd, b"checkqr\x00" as *const u8 as *const libc::c_char) == 0i32 {
|
} else if strcmp(cmd, b"checkqr\x00" as *const u8 as *const libc::c_char) == 0i32 {
|
||||||
if !arg1.is_empty() {
|
if !arg1.is_empty() {
|
||||||
let res: *mut dc_lot_t = dc_check_qr(context, arg1_c.as_ptr());
|
let res: *mut dc_lot_t = dc_check_qr(context, arg1_c_ptr);
|
||||||
ret = dc_mprintf(
|
ret = dc_mprintf(
|
||||||
b"state=%i, id=%i, text1=%s, text2=%s\x00" as *const u8 as *const libc::c_char,
|
b"state=%i, id=%i, text1=%s, text2=%s\x00" as *const u8 as *const libc::c_char,
|
||||||
(*res).state as libc::c_int,
|
(*res).state as libc::c_int,
|
||||||
@@ -1588,7 +1593,7 @@ pub unsafe fn dc_cmdline(context: &Context, cmdline: &str) -> *mut libc::c_char
|
|||||||
|
|
||||||
if 0 != dc_read_file(
|
if 0 != dc_read_file(
|
||||||
context,
|
context,
|
||||||
arg1_c.as_ptr(),
|
arg1_c_ptr,
|
||||||
&mut buf as *mut *mut libc::c_uchar as *mut *mut libc::c_void,
|
&mut buf as *mut *mut libc::c_uchar as *mut *mut libc::c_void,
|
||||||
&mut buf_bytes,
|
&mut buf_bytes,
|
||||||
) {
|
) {
|
||||||
|
|||||||
@@ -418,6 +418,8 @@ unsafe fn main_0(argc: libc::c_int, argv: *mut *mut libc::c_char) -> libc::c_int
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
|
let _ = pretty_env_logger::try_init();
|
||||||
|
|
||||||
let mut args: Vec<*mut libc::c_char> = Vec::new();
|
let mut args: Vec<*mut libc::c_char> = Vec::new();
|
||||||
for arg in ::std::env::args() {
|
for arg in ::std::env::args() {
|
||||||
args.push(
|
args.push(
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ impl str::FromStr for EncryptPreference {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Parse and create [Autocrypt-headers](https://autocrypt.org/en/latest/level1.html#the-autocrypt-header).
|
/// Parse and create [Autocrypt-headers](https://autocrypt.org/en/latest/level1.html#the-autocrypt-header).
|
||||||
|
#[derive(Debug)]
|
||||||
pub struct Aheader {
|
pub struct Aheader {
|
||||||
pub addr: String,
|
pub addr: String,
|
||||||
pub public_key: Key,
|
pub public_key: Key,
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ pub struct Context {
|
|||||||
unsafe impl std::marker::Send for Context {}
|
unsafe impl std::marker::Send for Context {}
|
||||||
unsafe impl std::marker::Sync for Context {}
|
unsafe impl std::marker::Sync for Context {}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
pub struct RunningState {
|
pub struct RunningState {
|
||||||
pub ongoing_running: bool,
|
pub ongoing_running: bool,
|
||||||
pub shall_stop_ongoing: bool,
|
pub shall_stop_ongoing: bool,
|
||||||
@@ -80,7 +80,7 @@ impl Default for RunningState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
pub struct BobStatus {
|
pub struct BobStatus {
|
||||||
pub expects: i32,
|
pub expects: i32,
|
||||||
pub status: i32,
|
pub status: i32,
|
||||||
|
|||||||
@@ -350,23 +350,27 @@ unsafe fn fingerprint_equals_sender(
|
|||||||
fingerprint: *const libc::c_char,
|
fingerprint: *const libc::c_char,
|
||||||
contact_chat_id: uint32_t,
|
contact_chat_id: uint32_t,
|
||||||
) -> libc::c_int {
|
) -> libc::c_int {
|
||||||
|
if fingerprint.is_null() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
let mut fingerprint_equal: libc::c_int = 0i32;
|
let mut fingerprint_equal: libc::c_int = 0i32;
|
||||||
let contacts: *mut dc_array_t = dc_get_chat_contacts(context, contact_chat_id);
|
let contacts: *mut dc_array_t = dc_get_chat_contacts(context, contact_chat_id);
|
||||||
let contact: *mut dc_contact_t = dc_contact_new(context);
|
let contact: *mut dc_contact_t = dc_contact_new(context);
|
||||||
|
|
||||||
if !(dc_array_get_cnt(contacts) != 1) {
|
if !(dc_array_get_cnt(contacts) != 1) {
|
||||||
let peerstate = Peerstate::from_addr(
|
if !dc_contact_load_from_db(
|
||||||
context,
|
|
||||||
&context.sql.clone().read().unwrap(),
|
|
||||||
to_str((*contact).addr),
|
|
||||||
);
|
|
||||||
if !(!dc_contact_load_from_db(
|
|
||||||
contact,
|
contact,
|
||||||
&context.sql.clone().read().unwrap(),
|
&context.sql.clone().read().unwrap(),
|
||||||
dc_array_get_id(contacts, 0i32 as size_t),
|
dc_array_get_id(contacts, 0i32 as size_t),
|
||||||
) || peerstate.is_some())
|
) {
|
||||||
{
|
return 0;
|
||||||
let peerstate = peerstate.as_ref().unwrap();
|
}
|
||||||
|
|
||||||
|
if let Some(peerstate) = Peerstate::from_addr(
|
||||||
|
context,
|
||||||
|
&context.sql.clone().read().unwrap(),
|
||||||
|
to_str((*contact).addr),
|
||||||
|
) {
|
||||||
let fingerprint_normalized = dc_normalize_fingerprint(to_str(fingerprint));
|
let fingerprint_normalized = dc_normalize_fingerprint(to_str(fingerprint));
|
||||||
if peerstate.public_key_fingerprint.is_some()
|
if peerstate.public_key_fingerprint.is_some()
|
||||||
&& &fingerprint_normalized == peerstate.public_key_fingerprint.as_ref().unwrap()
|
&& &fingerprint_normalized == peerstate.public_key_fingerprint.as_ref().unwrap()
|
||||||
|
|||||||
14
src/key.rs
14
src/key.rs
@@ -99,21 +99,17 @@ impl Key {
|
|||||||
match res {
|
match res {
|
||||||
Ok(key) => Some(key),
|
Ok(key) => Some(key),
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
eprintln!("Invalid key bytes: {:?}\n{}", err, hex::encode(bytes));
|
eprintln!("Invalid key bytes: {:?}", err);
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_binary(
|
pub fn from_binary(data: *const u8, len: libc::c_int, key_type: KeyType) -> Option<Self> {
|
||||||
data: *const libc::c_void,
|
|
||||||
len: libc::c_int,
|
|
||||||
key_type: KeyType,
|
|
||||||
) -> Option<Self> {
|
|
||||||
assert!(!data.is_null(), "missing data");
|
assert!(!data.is_null(), "missing data");
|
||||||
assert!(len > 0);
|
assert!(len > 0);
|
||||||
|
|
||||||
let bytes = unsafe { slice::from_raw_parts(data as *const u8, len as usize) };
|
let bytes = unsafe { slice::from_raw_parts(data, len as usize) };
|
||||||
Self::from_slice(bytes, key_type)
|
Self::from_slice(bytes, key_type)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -124,9 +120,7 @@ impl Key {
|
|||||||
) -> Option<Self> {
|
) -> Option<Self> {
|
||||||
assert!(!stmt.is_null(), "missing statement");
|
assert!(!stmt.is_null(), "missing statement");
|
||||||
|
|
||||||
let data = unsafe {
|
let data = unsafe { sqlite3_column_blob(stmt, index) as *const u8 };
|
||||||
sqlite3_column_blob(stmt, index) as *mut libc::c_uchar as *const libc::c_void
|
|
||||||
};
|
|
||||||
let len = unsafe { sqlite3_column_bytes(stmt, index) };
|
let len = unsafe { sqlite3_column_bytes(stmt, index) };
|
||||||
|
|
||||||
Self::from_binary(data, len, key_type)
|
Self::from_binary(data, len, key_type)
|
||||||
|
|||||||
318
src/peerstate.rs
318
src/peerstate.rs
@@ -1,5 +1,6 @@
|
|||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
use std::ffi::CString;
|
use std::ffi::CString;
|
||||||
|
use std::fmt;
|
||||||
|
|
||||||
use num_traits::FromPrimitive;
|
use num_traits::FromPrimitive;
|
||||||
|
|
||||||
@@ -30,6 +31,46 @@ pub struct Peerstate<'a> {
|
|||||||
pub degrade_event: Option<DegradeEvent>,
|
pub degrade_event: Option<DegradeEvent>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a> PartialEq for Peerstate<'a> {
|
||||||
|
fn eq(&self, other: &Peerstate) -> bool {
|
||||||
|
self.addr == other.addr
|
||||||
|
&& self.last_seen == other.last_seen
|
||||||
|
&& self.last_seen_autocrypt == other.last_seen_autocrypt
|
||||||
|
&& self.prefer_encrypt == other.prefer_encrypt
|
||||||
|
&& self.public_key == other.public_key
|
||||||
|
&& self.public_key_fingerprint == other.public_key_fingerprint
|
||||||
|
&& self.gossip_key == other.gossip_key
|
||||||
|
&& self.gossip_timestamp == other.gossip_timestamp
|
||||||
|
&& self.gossip_key_fingerprint == other.gossip_key_fingerprint
|
||||||
|
&& self.verified_key == other.verified_key
|
||||||
|
&& self.verified_key_fingerprint == other.verified_key_fingerprint
|
||||||
|
&& self.to_save == other.to_save
|
||||||
|
&& self.degrade_event == other.degrade_event
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Eq for Peerstate<'a> {}
|
||||||
|
|
||||||
|
impl<'a> fmt::Debug for Peerstate<'a> {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
f.debug_struct("Peerstate")
|
||||||
|
.field("addr", &self.addr)
|
||||||
|
.field("last_seen", &self.last_seen)
|
||||||
|
.field("last_seen_autocrypt", &self.last_seen_autocrypt)
|
||||||
|
.field("prefer_encrypt", &self.prefer_encrypt)
|
||||||
|
.field("public_key", &self.public_key)
|
||||||
|
.field("public_key_fingerprint", &self.public_key_fingerprint)
|
||||||
|
.field("gossip_key", &self.gossip_key)
|
||||||
|
.field("gossip_timestamp", &self.gossip_timestamp)
|
||||||
|
.field("gossip_key_fingerprint", &self.gossip_key_fingerprint)
|
||||||
|
.field("verified_key", &self.verified_key)
|
||||||
|
.field("verified_key_fingerprint", &self.verified_key_fingerprint)
|
||||||
|
.field("to_save", &self.to_save)
|
||||||
|
.field("degrade_event", &self.degrade_event)
|
||||||
|
.finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, FromPrimitive, ToPrimitive)]
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, FromPrimitive, ToPrimitive)]
|
||||||
#[repr(u8)]
|
#[repr(u8)]
|
||||||
pub enum ToSave {
|
pub enum ToSave {
|
||||||
@@ -46,7 +87,7 @@ pub enum DegradeEvent {
|
|||||||
FingerprintChanged = 0x02,
|
FingerprintChanged = 0x02,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone)]
|
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||||
pub enum VerifiedKey {
|
pub enum VerifiedKey {
|
||||||
Gossip,
|
Gossip,
|
||||||
Public,
|
Public,
|
||||||
@@ -187,15 +228,12 @@ impl<'a> Peerstate<'a> {
|
|||||||
res.prefer_encrypt =
|
res.prefer_encrypt =
|
||||||
EncryptPreference::from_i32(unsafe { sqlite3_column_int(stmt, 3) }).unwrap_or_default();
|
EncryptPreference::from_i32(unsafe { sqlite3_column_int(stmt, 3) }).unwrap_or_default();
|
||||||
res.gossip_timestamp = unsafe { sqlite3_column_int(stmt, 5) } as u64;
|
res.gossip_timestamp = unsafe { sqlite3_column_int(stmt, 5) } as u64;
|
||||||
res.public_key_fingerprint = Some(to_string(unsafe {
|
let pkf = to_string(unsafe { sqlite3_column_text(stmt, 7) as *const _ });
|
||||||
sqlite3_column_text(stmt, 7) as *const _
|
res.public_key_fingerprint = if pkf.is_empty() { None } else { Some(pkf) };
|
||||||
}));
|
let gkf = to_string(unsafe { sqlite3_column_text(stmt, 8) as *const _ });
|
||||||
res.gossip_key_fingerprint = Some(to_string(unsafe {
|
res.gossip_key_fingerprint = if gkf.is_empty() { None } else { Some(gkf) };
|
||||||
sqlite3_column_text(stmt, 8) as *const _
|
let vkf = to_string(unsafe { sqlite3_column_text(stmt, 10) as *const _ });
|
||||||
}));
|
res.verified_key_fingerprint = if vkf.is_empty() { None } else { Some(vkf) };
|
||||||
res.verified_key_fingerprint = Some(to_string(unsafe {
|
|
||||||
sqlite3_column_text(stmt, 10) as *const _
|
|
||||||
}));
|
|
||||||
|
|
||||||
if unsafe { sqlite3_column_type(stmt, 4) } != 5 {
|
if unsafe { sqlite3_column_type(stmt, 4) } != 5 {
|
||||||
res.public_key = Key::from_stmt(stmt, 4, KeyType::Public);
|
res.public_key = Key::from_stmt(stmt, 4, KeyType::Public);
|
||||||
@@ -382,7 +420,7 @@ impl<'a> Peerstate<'a> {
|
|||||||
as *const libc::c_char,
|
as *const libc::c_char,
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
let addr_c = CString::new(self.addr.as_ref().unwrap().as_bytes()).unwrap();
|
let addr_c = to_cstring(self.addr.as_ref().unwrap());
|
||||||
unsafe {
|
unsafe {
|
||||||
sqlite3_bind_text(stmt, 1, addr_c.as_ptr(), -1, None);
|
sqlite3_bind_text(stmt, 1, addr_c.as_ptr(), -1, None);
|
||||||
sqlite3_step(stmt);
|
sqlite3_step(stmt);
|
||||||
@@ -393,103 +431,104 @@ impl<'a> Peerstate<'a> {
|
|||||||
if self.to_save == Some(ToSave::All) || create {
|
if self.to_save == Some(ToSave::All) || create {
|
||||||
let stmt = unsafe {
|
let stmt = unsafe {
|
||||||
dc_sqlite3_prepare(
|
dc_sqlite3_prepare(
|
||||||
self.context,sql,
|
self.context, sql,
|
||||||
b"UPDATE acpeerstates SET last_seen=?, last_seen_autocrypt=?, prefer_encrypted=?, public_key=?, gossip_timestamp=?, gossip_key=?, public_key_fingerprint=?, gossip_key_fingerprint=?, verified_key=?, verified_key_fingerprint=? WHERE addr=?;\x00"
|
b"UPDATE acpeerstates \
|
||||||
as *const u8 as *const libc::c_char)
|
SET last_seen=?, last_seen_autocrypt=?, prefer_encrypted=?, \
|
||||||
|
public_key=?, gossip_timestamp=?, gossip_key=?, public_key_fingerprint=?, gossip_key_fingerprint=?, verified_key=?, verified_key_fingerprint=? \
|
||||||
|
WHERE addr=?;\x00"
|
||||||
|
as *const u8 as *const libc::c_char
|
||||||
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
unsafe {
|
unsafe { sqlite3_bind_int64(stmt, 1, self.last_seen as sqlite3_int64) };
|
||||||
sqlite3_bind_int64(stmt, 1, self.last_seen as sqlite3_int64);
|
unsafe { sqlite3_bind_int64(stmt, 2, self.last_seen_autocrypt as sqlite3_int64) };
|
||||||
sqlite3_bind_int64(stmt, 2, self.last_seen_autocrypt as sqlite3_int64);
|
unsafe { sqlite3_bind_int64(stmt, 3, self.prefer_encrypt as sqlite3_int64) };
|
||||||
sqlite3_bind_int64(stmt, 3, self.prefer_encrypt as sqlite3_int64);
|
|
||||||
}
|
|
||||||
|
|
||||||
let addr_c = self.addr.as_ref().map(|addr| to_cstring(addr));
|
let pub_bytes = self
|
||||||
let pub_bytes = self.public_key.as_ref().map(|k| k.to_bytes());
|
.public_key
|
||||||
let gossip_bytes = self.gossip_key.as_ref().map(|k| k.to_bytes());
|
.as_ref()
|
||||||
let ver_bytes = self.verified_key().map(|k| k.to_bytes());
|
.map(|k| k.to_bytes())
|
||||||
|
.unwrap_or_default();
|
||||||
|
let gossip_bytes = self
|
||||||
|
.gossip_key
|
||||||
|
.as_ref()
|
||||||
|
.map(|k| k.to_bytes())
|
||||||
|
.unwrap_or_default();
|
||||||
|
let ver_bytes = self
|
||||||
|
.verified_key()
|
||||||
|
.as_ref()
|
||||||
|
.map(|k| k.to_bytes())
|
||||||
|
.unwrap_or_default();
|
||||||
|
|
||||||
|
let pkc = self
|
||||||
|
.public_key_fingerprint
|
||||||
|
.as_ref()
|
||||||
|
.map(to_cstring)
|
||||||
|
.unwrap_or_default();
|
||||||
|
|
||||||
|
let pkc_ptr = if self.public_key_fingerprint.is_some() {
|
||||||
|
pkc.as_ptr()
|
||||||
|
} else {
|
||||||
|
std::ptr::null()
|
||||||
|
};
|
||||||
|
|
||||||
|
let gkc = self
|
||||||
|
.gossip_key_fingerprint
|
||||||
|
.as_ref()
|
||||||
|
.map(to_cstring)
|
||||||
|
.unwrap_or_default();
|
||||||
|
|
||||||
|
let gkc_ptr = if self.gossip_key_fingerprint.is_some() {
|
||||||
|
gkc.as_ptr()
|
||||||
|
} else {
|
||||||
|
std::ptr::null_mut()
|
||||||
|
};
|
||||||
|
let vkc = self
|
||||||
|
.verified_key_fingerprint
|
||||||
|
.as_ref()
|
||||||
|
.map(to_cstring)
|
||||||
|
.unwrap_or_default();
|
||||||
|
let vkc_ptr = if self.verified_key_fingerprint.is_some() {
|
||||||
|
vkc.as_ptr()
|
||||||
|
} else {
|
||||||
|
std::ptr::null_mut()
|
||||||
|
};
|
||||||
|
let addr: String = self.addr.clone().unwrap_or_default();
|
||||||
|
let addr_c = to_cstring(addr);
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
sqlite3_bind_blob(
|
sqlite3_bind_blob(
|
||||||
stmt,
|
stmt,
|
||||||
4,
|
4,
|
||||||
pub_bytes
|
pub_bytes.as_ptr() as *const _,
|
||||||
.as_ref()
|
pub_bytes.len() as libc::c_int,
|
||||||
.map(|b| b.as_ptr())
|
SQLITE_TRANSIENT(),
|
||||||
.unwrap_or_else(|| std::ptr::null()) as *const _,
|
)
|
||||||
pub_bytes.as_ref().map(|b| b.len()).unwrap_or_else(|| 0) as libc::c_int,
|
};
|
||||||
None,
|
unsafe { sqlite3_bind_int64(stmt, 5, self.gossip_timestamp as sqlite3_int64) };
|
||||||
);
|
unsafe {
|
||||||
sqlite3_bind_int64(stmt, 5, self.gossip_timestamp as sqlite3_int64);
|
|
||||||
sqlite3_bind_blob(
|
sqlite3_bind_blob(
|
||||||
stmt,
|
stmt,
|
||||||
6,
|
6,
|
||||||
gossip_bytes
|
gossip_bytes.as_ptr() as *const _,
|
||||||
.as_ref()
|
gossip_bytes.len() as libc::c_int,
|
||||||
.map(|b| b.as_ptr())
|
SQLITE_TRANSIENT(),
|
||||||
.unwrap_or_else(|| std::ptr::null()) as *const _,
|
)
|
||||||
gossip_bytes.as_ref().map(|b| b.len()).unwrap_or_else(|| 0) as libc::c_int,
|
};
|
||||||
None,
|
unsafe { sqlite3_bind_text(stmt, 7, pkc_ptr as *const _, -1, SQLITE_TRANSIENT()) };
|
||||||
);
|
unsafe { sqlite3_bind_text(stmt, 8, gkc_ptr as *const _, -1, SQLITE_TRANSIENT()) };
|
||||||
let pkc = self
|
unsafe {
|
||||||
.public_key_fingerprint
|
|
||||||
.as_ref()
|
|
||||||
.map(|fp| to_cstring(fp));
|
|
||||||
let gkc = self
|
|
||||||
.gossip_key_fingerprint
|
|
||||||
.as_ref()
|
|
||||||
.map(|fp| to_cstring(fp));
|
|
||||||
|
|
||||||
sqlite3_bind_text(
|
|
||||||
stmt,
|
|
||||||
7,
|
|
||||||
pkc.map(|fp| fp.as_ptr())
|
|
||||||
.unwrap_or_else(|| std::ptr::null()),
|
|
||||||
-1,
|
|
||||||
None,
|
|
||||||
);
|
|
||||||
sqlite3_bind_text(
|
|
||||||
stmt,
|
|
||||||
8,
|
|
||||||
gkc.map(|fp| fp.as_ptr())
|
|
||||||
.unwrap_or_else(|| std::ptr::null()),
|
|
||||||
-1,
|
|
||||||
None,
|
|
||||||
);
|
|
||||||
sqlite3_bind_blob(
|
sqlite3_bind_blob(
|
||||||
stmt,
|
stmt,
|
||||||
9,
|
9,
|
||||||
ver_bytes
|
ver_bytes.as_ptr() as *const _,
|
||||||
.as_ref()
|
ver_bytes.len() as libc::c_int,
|
||||||
.map(|b| b.as_ptr())
|
SQLITE_TRANSIENT(),
|
||||||
.unwrap_or_else(|| std::ptr::null()) as *const _,
|
)
|
||||||
ver_bytes.as_ref().map(|b| b.len()).unwrap_or_else(|| 0) as libc::c_int,
|
};
|
||||||
None,
|
|
||||||
);
|
|
||||||
|
|
||||||
let vkc = self
|
unsafe { sqlite3_bind_text(stmt, 10, vkc_ptr as *const _, -1, SQLITE_TRANSIENT()) };
|
||||||
.verified_key_fingerprint
|
unsafe { sqlite3_bind_text(stmt, 11, addr_c.as_ptr(), -1, SQLITE_TRANSIENT()) };
|
||||||
.as_ref()
|
|
||||||
.map(|fp| to_cstring(fp));
|
|
||||||
|
|
||||||
sqlite3_bind_text(
|
|
||||||
stmt,
|
|
||||||
10,
|
|
||||||
vkc.map(|fp| fp.as_ptr())
|
|
||||||
.unwrap_or_else(|| std::ptr::null()),
|
|
||||||
-1,
|
|
||||||
None,
|
|
||||||
);
|
|
||||||
sqlite3_bind_text(
|
|
||||||
stmt,
|
|
||||||
11,
|
|
||||||
addr_c
|
|
||||||
.map(|addr| addr.as_ptr())
|
|
||||||
.unwrap_or_else(|| std::ptr::null()),
|
|
||||||
-1,
|
|
||||||
None,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if unsafe { sqlite3_step(stmt) } == 101 {
|
if unsafe { sqlite3_step(stmt) } == 101 {
|
||||||
success = true;
|
success = true;
|
||||||
@@ -506,10 +545,10 @@ impl<'a> Peerstate<'a> {
|
|||||||
|
|
||||||
let addr_c = self.addr.as_ref().map(|fp| to_cstring(fp));
|
let addr_c = self.addr.as_ref().map(|fp| to_cstring(fp));
|
||||||
|
|
||||||
|
unsafe { sqlite3_bind_int64(stmt, 1, self.last_seen as sqlite3_int64) };
|
||||||
|
unsafe { sqlite3_bind_int64(stmt, 2, self.last_seen_autocrypt as sqlite3_int64) };
|
||||||
|
unsafe { sqlite3_bind_int64(stmt, 3, self.gossip_timestamp as sqlite3_int64) };
|
||||||
unsafe {
|
unsafe {
|
||||||
sqlite3_bind_int64(stmt, 1, self.last_seen as sqlite3_int64);
|
|
||||||
sqlite3_bind_int64(stmt, 2, self.last_seen_autocrypt as sqlite3_int64);
|
|
||||||
sqlite3_bind_int64(stmt, 3, self.gossip_timestamp as sqlite3_int64);
|
|
||||||
sqlite3_bind_text(
|
sqlite3_bind_text(
|
||||||
stmt,
|
stmt,
|
||||||
4,
|
4,
|
||||||
@@ -517,9 +556,9 @@ impl<'a> Peerstate<'a> {
|
|||||||
.map(|addr| addr.as_ptr())
|
.map(|addr| addr.as_ptr())
|
||||||
.unwrap_or_else(|| std::ptr::null()),
|
.unwrap_or_else(|| std::ptr::null()),
|
||||||
-1,
|
-1,
|
||||||
None,
|
SQLITE_TRANSIENT(),
|
||||||
);
|
)
|
||||||
}
|
};
|
||||||
|
|
||||||
if unsafe { sqlite3_step(stmt) } == 101 {
|
if unsafe { sqlite3_step(stmt) } == 101 {
|
||||||
success = true;
|
success = true;
|
||||||
@@ -546,3 +585,84 @@ impl<'a> Peerstate<'a> {
|
|||||||
false
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
use pretty_assertions::assert_eq;
|
||||||
|
|
||||||
|
use std::ffi::CStr;
|
||||||
|
use tempfile::{tempdir, TempDir};
|
||||||
|
|
||||||
|
use crate::context::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_peerstate_save_to_db() {
|
||||||
|
let ctx = unsafe { create_test_context() };
|
||||||
|
let addr = "hello@mail.com";
|
||||||
|
|
||||||
|
let pub_key = crate::key::Key::from_base64("xsBNBFztUVkBCADYaQl/UOUpRPd32nLRzx8eU0eI+jQEnG+g5anjYA+3oct1rROGl5SygjMULDKdaUy27O3o9Srsti0YjA7uxZnavIqhSopJhFidqY1M1wA9JZa/duucZdNwUGbjGIRsS/4Cjr5+3svscK24hVYub1dvDWXpwUTnj3K6xOEnJdoM+MhCqtSD5+zcJhFc9vyZm9ZTGWUxAhKh0iJTcCD8V6CQ3XZ2z9GruwzZT/FTFovWrz7m3TUI2OdSSHh0eZLRGEoxMCT/vzflAFGAr8ijCaRsEIfqP6FW8uQWnFTqkjxEUCZG6XkeFHB84aj5jqYG/1KCLjL5vEKwfl1tz/WnPhY7ABEBAAHNEDxoZWxsb0BtYWlsLmNvbT7CwIkEEAEIADMCGQEFAlztUVoCGwMECwkIBwYVCAkKCwIDFgIBFiEEgMjHGVbvLXe6ioRROg8oKCvye7gACgkQOg8oKCvye7ijAwf+PTsuawUax9cNPn1bN90H+g9qyHZJMEwKXtUnNaXJxPW3iB7ThhpCiCzsZwP7+l7ArS8tmLeNDw2bENtcf1XCv4wovP2fdXOP3QOUUFX/GdakcTwv7DzC7CO0grB1HtaPhGw/6UX2o2cx2i9xiUf4Givq2MfCbgAW5zloH6WXGPb6yLQYJXxqDIphr4+uZDb+bMAyWHN/DUkAjHrV8nnVki7PMHqzzZpwglalxMX8RGeiGZE39ALJKL/Og87DMFah87/yoxQWGoS7Wqv0XDcCPKoTCPrpk8pOe2KEsq/lz215nefHd4aRpfUX5YCYa8HPvvfPQbGF73uvyQw5w7qjis7ATQRc7VFZAQgAt8ONdnX6KEEQ5Jw6ilJ+LBtY44SP5t0I3eK+goKepgIiKhjGDa+Mntyi4jdhH+HO6kvK5SHMh2sPp4rRO/WKHJwWFySyM1OdyiywhyH0J9R5rBY4vPHsJjf6vSKJdWLWT+ho1fNet2IIC+jVCYli91MAMbRvk6EKVj1nCc+67giOahXEkHt6xxkeCGlOvbw8hxGj1A8+AC1BLms/OR3oc4JMi9O3kq6uG0z9tlUEerac9HVwcjoO1XLe+hJhoT5H+TbnGjPuhuURP3pFiIKHpbRYgUfdSAY0dTObO7t4I5y/drPOrCTnWrBUg2wXAECUhpRKow9/ai2YemLv9KqhhwARAQABwsB2BBgBCAAgBQJc7VFaAhsMFiEEgMjHGVbvLXe6ioRROg8oKCvye7gACgkQOg8oKCvye7jmyggAhs4QzCzIbT2OsAReBxkxtm0AI+g1HZ1KFKof5NDHfgv9C/Qu1I8mKEjlZzA4qFyPmLqntgwJ0RuFy6gLbljZBNCFO7vB478AhYtnWjuKZmA40HUPwcB1hEJ31c42akzfUbioY1TLLepngdsJg7Cm8O+rhI9+1WRA66haJDgFs793SVUDyJh8f9NX50l5zR87/bsV30CFSw0q4OSSy9VI/z+2g5khn1LnuuOrCfFnYIPYtJED1BfkXkosxGlgbzy79VvGmI9d23x4atDK7oBPCzIj+lP8sytJ0u3HOguXi9OgDitKy+Pt1r8gH8frdktMJr5Ts6DW+tIn2vR23KR8aA==", KeyType::Public).unwrap();
|
||||||
|
|
||||||
|
let mut peerstate = Peerstate {
|
||||||
|
context: &ctx.ctx,
|
||||||
|
addr: Some(addr.into()),
|
||||||
|
last_seen: 10,
|
||||||
|
last_seen_autocrypt: 11,
|
||||||
|
prefer_encrypt: EncryptPreference::Mutual,
|
||||||
|
public_key: Some(pub_key.clone()),
|
||||||
|
public_key_fingerprint: Some(pub_key.fingerprint()),
|
||||||
|
gossip_key: Some(pub_key.clone()),
|
||||||
|
gossip_timestamp: 12,
|
||||||
|
gossip_key_fingerprint: Some(pub_key.fingerprint()),
|
||||||
|
verified_key: VerifiedKey::Gossip,
|
||||||
|
verified_key_fingerprint: Some(pub_key.fingerprint()),
|
||||||
|
to_save: Some(ToSave::All),
|
||||||
|
degrade_event: None,
|
||||||
|
};
|
||||||
|
|
||||||
|
assert!(
|
||||||
|
peerstate.save_to_db(&ctx.ctx.sql.clone().read().unwrap(), true),
|
||||||
|
"failed to save"
|
||||||
|
);
|
||||||
|
|
||||||
|
let peerstate_new =
|
||||||
|
Peerstate::from_addr(&ctx.ctx, &ctx.ctx.sql.clone().read().unwrap(), addr.into())
|
||||||
|
.expect("failed to load peerstate from db");
|
||||||
|
|
||||||
|
// clear to_save, as that is not persissted
|
||||||
|
peerstate.to_save = None;
|
||||||
|
assert_eq!(peerstate, peerstate_new);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: don't copy this from stress.rs
|
||||||
|
#[allow(dead_code)]
|
||||||
|
struct TestContext {
|
||||||
|
ctx: Context,
|
||||||
|
dir: TempDir,
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe extern "C" fn cb(
|
||||||
|
_context: &Context,
|
||||||
|
_event: Event,
|
||||||
|
_data1: uintptr_t,
|
||||||
|
_data2: uintptr_t,
|
||||||
|
) -> uintptr_t {
|
||||||
|
0
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe fn create_test_context() -> TestContext {
|
||||||
|
let mut ctx = dc_context_new(cb, std::ptr::null_mut(), std::ptr::null_mut());
|
||||||
|
let dir = tempdir().unwrap();
|
||||||
|
let dbfile = CString::new(dir.path().join("db.sqlite").to_str().unwrap()).unwrap();
|
||||||
|
assert_eq!(
|
||||||
|
dc_open(&mut ctx, dbfile.as_ptr(), std::ptr::null()),
|
||||||
|
1,
|
||||||
|
"Failed to open {}",
|
||||||
|
CStr::from_ptr(dbfile.as_ptr() as *const libc::c_char)
|
||||||
|
.to_str()
|
||||||
|
.unwrap()
|
||||||
|
);
|
||||||
|
|
||||||
|
TestContext { ctx: ctx, dir: dir }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -2213,8 +2213,7 @@ fn test_encryption_decryption() {
|
|||||||
|
|
||||||
while j < 4096 / 40 {
|
while j < 4096 / 40 {
|
||||||
let bad_key = Key::from_binary(
|
let bad_key = Key::from_binary(
|
||||||
&mut *bad_data.as_mut_ptr().offset(j as isize) as *mut libc::c_uchar
|
&mut *bad_data.as_mut_ptr().offset(j as isize) as *const u8,
|
||||||
as *const libc::c_void,
|
|
||||||
4096 / 2 + j,
|
4096 / 2 + j,
|
||||||
if 0 != j & 1 {
|
if 0 != j & 1 {
|
||||||
KeyType::Public
|
KeyType::Public
|
||||||
|
|||||||
Reference in New Issue
Block a user