Merge pull request #496 from KAction/safe

Make dc_msg_get_file return PathBuf, not char*
This commit is contained in:
Alexander Krotov
2019-09-13 00:43:28 +00:00
committed by GitHub
19 changed files with 127 additions and 228 deletions

View File

@@ -17,7 +17,7 @@ use std::ptr;
use std::str::FromStr;
use deltachat::contact::Contact;
use deltachat::dc_tools::{as_str, dc_strdup, StrExt};
use deltachat::dc_tools::{as_str, dc_strdup, OsStrExt, StrExt};
use deltachat::*;
// as C lacks a good and portable error handling,
@@ -2013,6 +2013,9 @@ pub unsafe extern "C" fn dc_msg_get_file(msg: *mut dc_msg_t) -> *mut libc::c_cha
}
let ffi_msg = &*msg;
message::dc_msg_get_file(&*ffi_msg.context, &ffi_msg.message)
.and_then(|p| p.to_c_string().ok())
.map(|cs| dc_strdup(cs.as_ptr()))
.unwrap_or_else(|| dc_strdup(ptr::null()))
}
#[no_mangle]

View File

@@ -7,7 +7,6 @@ use mmime::mailimf_types::*;
use crate::constants::*;
use crate::contact::*;
use crate::dc_tools::as_str;
use crate::key::*;
/// Possible values for encryption preference
@@ -64,11 +63,8 @@ impl Aheader {
}
}
pub fn from_imffields(
wanted_from: *const libc::c_char,
header: *const mailimf_fields,
) -> Option<Self> {
if wanted_from.is_null() || header.is_null() {
pub fn from_imffields(wanted_from: &str, header: *const mailimf_fields) -> Option<Self> {
if header.is_null() {
return None;
}
@@ -94,7 +90,7 @@ impl Aheader {
match Self::from_str(value) {
Ok(test) => {
if addr_cmp(&test.addr, as_str(wanted_from)) {
if addr_cmp(&test.addr, wanted_from) {
if fine_header.is_none() {
fine_header = Some(test);
} else {

View File

@@ -2,6 +2,7 @@ use std::ffi::CString;
use std::path::{Path, PathBuf};
use crate::chatlist::*;
use crate::config::*;
use crate::constants::*;
use crate::contact::*;
use crate::context::Context;
@@ -59,15 +60,13 @@ impl Chat {
match res {
Err(err @ crate::error::Error::Sql(rusqlite::Error::QueryReturnedNoRows)) => Err(err),
Err(err) => match err {
_ => {
error!(
context,
"chat: failed to load from db {}: {:?}", chat_id, err
);
Err(err)
}
},
Err(err) => {
error!(
context,
"chat: failed to load from db {}: {:?}", chat_id, err
);
Err(err)
}
Ok(mut chat) => {
match chat.id {
DC_CHAT_ID_DEADDROP => {
@@ -140,13 +139,12 @@ impl Chat {
if self.typ == Chattype::Single {
return context
.sql
.query_row_col(
.query_get_value(
context,
"SELECT c.addr FROM chats_contacts cc \
LEFT JOIN contacts c ON c.id=cc.contact_id \
WHERE cc.chat_id=?;",
params![self.id as i32],
0,
)
.unwrap_or_else(|| "Err".into());
}
@@ -183,7 +181,7 @@ impl Chat {
pub fn get_profile_image(&self, context: &Context) -> Option<PathBuf> {
if let Some(image_rel) = self.param.get(Param::ProfileImage) {
if !image_rel.is_empty() {
return Some(dc_get_abs_path_safe(context, image_rel));
return Some(dc_get_abs_path(context, image_rel));
}
} else if self.typ == Chattype::Single {
let contacts = get_chat_contacts(context, self.id);
@@ -269,7 +267,7 @@ impl Chat {
return Ok(0);
}
if let Some(from) = context.sql.get_config(context, "configured_addr") {
if let Some(from) = context.get_config(Config::ConfiguredAddr) {
let new_rfc724_mid = {
let grpid = match self.typ {
Chattype::Group | Chattype::VerifiedGroup => Some(self.grpid.as_str()),
@@ -279,11 +277,10 @@ impl Chat {
};
if self.typ == Chattype::Single {
if let Some(id) = context.sql.query_row_col(
if let Some(id) = context.sql.query_get_value(
context,
"SELECT contact_id FROM chats_contacts WHERE chat_id=?;",
params![self.id as i32],
0,
) {
to_id = id;
} else {
@@ -724,13 +721,12 @@ fn prepare_msg_common(context: &Context, chat_id: u32, msg: &mut Message) -> Res
}
fn last_msg_in_chat_encrypted(context: &Context, sql: &Sql, chat_id: u32) -> bool {
let packed: Option<String> = sql.query_row_col(
let packed: Option<String> = sql.query_get_value(
context,
"SELECT param \
FROM msgs WHERE timestamp=(SELECT MAX(timestamp) FROM msgs WHERE chat_id=?) \
ORDER BY id DESC;",
params![chat_id as i32],
0,
);
if let Some(ref packed) = packed {
@@ -912,11 +908,10 @@ unsafe fn set_draft_raw(context: &Context, chat_id: u32, mut msg: Option<&mut Me
fn get_draft_msg_id(context: &Context, chat_id: u32) -> u32 {
context
.sql
.query_row_col::<_, i32>(
.query_get_value::<_, i32>(
context,
"SELECT id FROM msgs WHERE chat_id=? AND state=?;",
params![chat_id as i32, MessageState::OutDraft],
0,
)
.unwrap_or_default() as u32
}
@@ -1007,11 +1002,10 @@ pub fn get_chat_msgs(context: &Context, chat_id: u32, flags: u32, marker1before:
pub fn get_msg_cnt(context: &Context, chat_id: u32) -> usize {
context
.sql
.query_row_col::<_, i32>(
.query_get_value::<_, i32>(
context,
"SELECT COUNT(*) FROM msgs WHERE chat_id=?;",
params![chat_id as i32],
0,
)
.unwrap_or_default() as usize
}
@@ -1019,14 +1013,13 @@ pub fn get_msg_cnt(context: &Context, chat_id: u32) -> usize {
pub fn get_fresh_msg_cnt(context: &Context, chat_id: u32) -> usize {
context
.sql
.query_row_col::<_, i32>(
.query_get_value::<_, i32>(
context,
"SELECT COUNT(*) FROM msgs \
WHERE state=10 \
AND hidden=0 \
AND chat_id=?;",
params![chat_id as i32],
0,
)
.unwrap_or_default() as usize
}
@@ -1791,11 +1784,10 @@ pub unsafe fn forward_msgs(
pub fn get_chat_contact_cnt(context: &Context, chat_id: u32) -> libc::c_int {
context
.sql
.query_row_col(
.query_get_value(
context,
"SELECT COUNT(*) FROM chats_contacts WHERE chat_id=?;",
params![chat_id as i32],
0,
)
.unwrap_or_default()
}
@@ -1805,11 +1797,10 @@ pub fn get_chat_cnt(context: &Context) -> usize {
/* no database, no chats - this is no error (needed eg. for information) */
context
.sql
.query_row_col::<_, isize>(
.query_get_value::<_, isize>(
context,
"SELECT COUNT(*) FROM chats WHERE id>9 AND blocked=0;",
params![],
0,
)
.unwrap_or_default() as usize
} else {

View File

@@ -301,11 +301,10 @@ impl Chatlist {
pub fn dc_get_archived_cnt(context: &Context) -> u32 {
context
.sql
.query_row_col(
.query_get_value(
context,
"SELECT COUNT(*) FROM chats WHERE blocked=0 AND archived=1;",
params![],
0,
)
.unwrap_or_default()
}
@@ -315,7 +314,7 @@ fn get_last_deaddrop_fresh_msg(context: &Context) -> u32 {
// only few fresh messages.
context
.sql
.query_row_col(
.query_get_value(
context,
"SELECT m.id FROM msgs m LEFT JOIN chats c ON c.id=m.chat_id \
WHERE m.state=10 \
@@ -323,7 +322,6 @@ fn get_last_deaddrop_fresh_msg(context: &Context) -> u32 {
AND c.blocked=2 \
ORDER BY m.timestamp DESC, m.id DESC;",
params![],
0,
)
.unwrap_or_default()
}

View File

@@ -73,7 +73,7 @@ impl Context {
let value = match key {
Config::Selfavatar => {
let rel_path = self.sql.get_config(self, key);
rel_path.map(|p| dc_get_abs_path_safe(self, &p).to_str().unwrap().to_string())
rel_path.map(|p| dc_get_abs_path(self, &p).to_str().unwrap().to_string())
}
Config::SysVersion => Some((&*DC_VERSION_STR).clone()),
Config::SysMsgsizeMaxRecommended => Some(format!("{}", 24 * 1024 * 1024 / 4 * 3)),

View File

@@ -264,7 +264,7 @@ impl Contact {
return 1;
}
context.sql.query_row_col(
context.sql.query_get_value(
context,
"SELECT id FROM contacts WHERE addr=?1 COLLATE NOCASE AND id>?2 AND origin>=?3 AND blocked=0;",
params![
@@ -272,7 +272,6 @@ impl Contact {
DC_CONTACT_ID_LAST_SPECIAL as i32,
DC_ORIGIN_MIN_CONTACT_LIST,
],
0
).unwrap_or_default()
}
@@ -538,11 +537,10 @@ impl Contact {
pub fn get_blocked_cnt(context: &Context) -> usize {
context
.sql
.query_row_col::<_, isize>(
.query_get_value::<_, isize>(
context,
"SELECT COUNT(*) FROM contacts WHERE id>? AND blocked!=0",
params![DC_CONTACT_ID_LAST_SPECIAL as i32],
0,
)
.unwrap_or_default() as usize
}
@@ -645,22 +643,20 @@ impl Contact {
let count_contacts: i32 = context
.sql
.query_row_col(
.query_get_value(
context,
"SELECT COUNT(*) FROM chats_contacts WHERE contact_id=?;",
params![contact_id as i32],
0,
)
.unwrap_or_default();
let count_msgs: i32 = if count_contacts > 0 {
context
.sql
.query_row_col(
.query_get_value(
context,
"SELECT COUNT(*) FROM msgs WHERE from_id=? OR to_id=?;",
params![contact_id as i32, contact_id as i32],
0,
)
.unwrap_or_default()
} else {
@@ -844,11 +840,10 @@ impl Contact {
context
.sql
.query_row_col::<_, isize>(
.query_get_value::<_, isize>(
context,
"SELECT COUNT(*) FROM contacts WHERE id>?;",
params![DC_CONTACT_ID_LAST_SPECIAL as i32],
0,
)
.unwrap_or_default() as usize
}

View File

@@ -349,18 +349,16 @@ pub unsafe fn dc_get_info(context: &Context) -> *mut libc::c_char {
.get_config_int(context, "mdns_enabled")
.unwrap_or_else(|| 1);
let prv_key_cnt: Option<isize> = context.sql.query_row_col(
let prv_key_cnt: Option<isize> = context.sql.query_get_value(
context,
"SELECT COUNT(*) FROM keypairs;",
rusqlite::NO_PARAMS,
0,
);
let pub_key_cnt: Option<isize> = context.sql.query_row_col(
let pub_key_cnt: Option<isize> = context.sql.query_get_value(
context,
"SELECT COUNT(*) FROM acpeerstates;",
rusqlite::NO_PARAMS,
0,
);
let fingerprint_str = if let Some(key) = Key::from_self_public(context, &l2.addr, &context.sql)
@@ -508,12 +506,12 @@ pub fn dc_search_msgs(
return Vec::new();
}
let real_query = to_string(query).trim().to_string();
let real_query = as_str(query).trim();
if real_query.is_empty() {
return Vec::new();
}
let strLikeInText = format!("%{}%", &real_query);
let strLikeBeg = format!("{}%", &real_query);
let strLikeInText = format!("%{}%", real_query);
let strLikeBeg = format!("{}%", real_query);
let query = if 0 != chat_id {
"SELECT m.id, m.timestamp FROM msgs m LEFT JOIN contacts ct ON m.from_id=ct.id WHERE m.chat_id=? \

View File

@@ -269,54 +269,48 @@ pub unsafe fn dc_continue_key_transfer(
setup_code: *const libc::c_char,
) -> bool {
let mut success = false;
let mut filename: *mut libc::c_char = ptr::null_mut();
let mut filecontent: *mut libc::c_char = ptr::null_mut();
let mut filebytes: size_t = 0i32 as size_t;
let mut armored_key: *mut libc::c_char = ptr::null_mut();
let mut norm_sc: *mut libc::c_char = ptr::null_mut();
let norm_sc;
if msg_id <= 9i32 as libc::c_uint || setup_code.is_null() {
return false;
}
let msg = dc_get_msg(context, msg_id);
if msg.is_err()
|| !dc_msg_is_setupmessage(msg.as_ref().unwrap())
|| {
filename = dc_msg_get_file(context, msg.as_ref().unwrap());
filename.is_null()
}
|| *filename.offset(0isize) as libc::c_int == 0i32
{
error!(context, "Message is no Autocrypt Setup Message.",);
} else if 0
== dc_read_file(
context,
filename,
&mut filecontent as *mut *mut libc::c_char as *mut *mut libc::c_void,
&mut filebytes,
)
|| filecontent.is_null()
|| filebytes <= 0
{
error!(context, "Cannot read Autocrypt Setup Message file.",);
} else {
norm_sc = dc_normalize_setup_code(context, setup_code);
if norm_sc.is_null() {
warn!(context, "Cannot normalize Setup Code.",);
} else {
armored_key = dc_decrypt_setup_file(context, norm_sc, filecontent);
if armored_key.is_null() {
warn!(context, "Cannot decrypt Autocrypt Setup Message.",);
} else if set_self_key(context, armored_key, 1) {
/*set default*/
/* error already logged */
success = true
if msg.is_err() {
error!(context, "Message is no Autocrypt Setup Message.");
return false;
}
let msg = msg.unwrap();
if !dc_msg_is_setupmessage(&msg) {
error!(context, "Message is no Autocrypt Setup Message.");
return false;
}
if let Some(filename) = dc_msg_get_file(context, &msg) {
if let Some(buf) = dc_read_file_safe(context, filename) {
norm_sc = dc_normalize_setup_code(context, setup_code);
if norm_sc.is_null() {
warn!(context, "Cannot normalize Setup Code.",);
} else {
armored_key = dc_decrypt_setup_file(context, norm_sc, buf.as_ptr().cast());
if armored_key.is_null() {
warn!(context, "Cannot decrypt Autocrypt Setup Message.",);
} else if set_self_key(context, armored_key, 1) {
/*set default*/
/* error already logged */
success = true
}
}
} else {
error!(context, "Cannot read Autocrypt Setup Message file.",);
return false;
}
} else {
error!(context, "Message is no Autocrypt Setup Message.");
return false;
}
free(armored_key as *mut libc::c_void);
free(filecontent as *mut libc::c_void);
free(filename as *mut libc::c_void);
free(norm_sc as *mut libc::c_void);
success
@@ -368,7 +362,7 @@ fn set_self_key(
error!(context, "File does not contain a private key.",);
}
let self_addr = context.sql.get_config(context, "configured_addr");
let self_addr = context.get_config(Config::ConfiguredAddr);
if self_addr.is_none() {
error!(context, "Missing self addr");
@@ -612,7 +606,7 @@ unsafe fn import_backup(context: &Context, backup_to_import: *const libc::c_char
let total_files_cnt = context
.sql
.query_row_col::<_, isize>(context, "SELECT COUNT(*) FROM backup_blobs;", params![], 0)
.query_get_value::<_, isize>(context, "SELECT COUNT(*) FROM backup_blobs;", params![])
.unwrap_or_default() as usize;
info!(
context,
@@ -1099,7 +1093,7 @@ unsafe fn export_key_to_asc_file(
}
info!(context, "Exporting key {}", as_str(file_name),);
dc_delete_file(context, as_path(file_name));
if !key.write_asc_to_file(file_name, context) {
if !key.write_asc_to_file(as_path(file_name), context) {
error!(context, "Cannot write key to {}", as_str(file_name),);
} else {
context.call_cb(

View File

@@ -1289,7 +1289,10 @@ unsafe fn build_body_file(
) as *mut libc::c_void,
);
mime_sub = mailmime_new_empty(content, mime_fields);
mailmime_set_body_file(mime_sub, dc_get_abs_path(context, path_filename));
let abs_path = dc_get_abs_path(context, path_filename)
.to_c_string()
.unwrap();
mailmime_set_body_file(mime_sub, dc_strdup(abs_path.as_ptr()));
if !ret_file_name_as_sent.is_null() {
*ret_file_name_as_sent = dc_strdup(filename_to_send)
}

View File

@@ -991,11 +991,10 @@ unsafe fn calc_timestamps(
}
*sort_timestamp = message_timestamp;
if 0 != is_fresh_msg {
let last_msg_time: Option<i64> = context.sql.query_row_col(
let last_msg_time: Option<i64> = context.sql.query_get_value(
context,
"SELECT MAX(timestamp) FROM msgs WHERE chat_id=? and from_id!=? AND timestamp>=?",
params![chat_id as i32, from_id as i32, *sort_timestamp],
0,
);
if let Some(last_msg_time) = last_msg_time {
if last_msg_time > 0 {

View File

@@ -792,7 +792,7 @@ pub fn dc_get_filemeta(buf: &[u8]) -> Result<(u32, u32), Error> {
///
/// If `path` starts with "$BLOBDIR", replaces it with the blobdir path.
/// Otherwise, returns path as is.
pub fn dc_get_abs_path_safe<P: AsRef<std::path::Path>>(
pub fn dc_get_abs_path<P: AsRef<std::path::Path>>(
context: &Context,
path: P,
) -> std::path::PathBuf {
@@ -808,33 +808,12 @@ pub fn dc_get_abs_path_safe<P: AsRef<std::path::Path>>(
}
}
pub unsafe fn dc_get_abs_path(
context: &Context,
path_filename: impl AsRef<str>,
) -> *mut libc::c_char {
let starts = path_filename.as_ref().starts_with("$BLOBDIR");
if starts && !context.has_blobdir() {
return ptr::null_mut();
}
let mut path_filename_abs = path_filename.as_ref().strdup();
if starts && context.has_blobdir() {
dc_str_replace(
&mut path_filename_abs,
b"$BLOBDIR\x00" as *const u8 as *const libc::c_char,
context.get_blobdir(),
);
}
path_filename_abs
}
pub fn dc_file_exist(context: &Context, path: impl AsRef<std::path::Path>) -> bool {
dc_get_abs_path_safe(context, &path).exists()
dc_get_abs_path(context, &path).exists()
}
pub fn dc_get_filebytes(context: &Context, path: impl AsRef<std::path::Path>) -> uint64_t {
let path_abs = dc_get_abs_path_safe(context, &path);
let path_abs = dc_get_abs_path(context, &path);
match fs::metadata(&path_abs) {
Ok(meta) => meta.len() as uint64_t,
Err(_err) => 0,
@@ -842,7 +821,7 @@ pub fn dc_get_filebytes(context: &Context, path: impl AsRef<std::path::Path>) ->
}
pub fn dc_delete_file(context: &Context, path: impl AsRef<std::path::Path>) -> bool {
let path_abs = dc_get_abs_path_safe(context, &path);
let path_abs = dc_get_abs_path(context, &path);
if !path_abs.is_file() {
warn!(
context,
@@ -866,8 +845,8 @@ pub fn dc_copy_file(
src: impl AsRef<std::path::Path>,
dest: impl AsRef<std::path::Path>,
) -> bool {
let src_abs = dc_get_abs_path_safe(context, &src);
let dest_abs = dc_get_abs_path_safe(context, &dest);
let src_abs = dc_get_abs_path(context, &src);
let dest_abs = dc_get_abs_path(context, &dest);
match fs::copy(&src_abs, &dest_abs) {
Ok(_) => true,
Err(_) => {
@@ -883,7 +862,7 @@ pub fn dc_copy_file(
}
pub fn dc_create_folder(context: &Context, path: impl AsRef<std::path::Path>) -> bool {
let path_abs = dc_get_abs_path_safe(context, &path);
let path_abs = dc_get_abs_path(context, &path);
if !path_abs.exists() {
match fs::create_dir_all(path_abs) {
Ok(_) => true,
@@ -918,7 +897,7 @@ pub fn dc_write_file_safe<P: AsRef<std::path::Path>>(
path: P,
buf: &[u8],
) -> bool {
let path_abs = dc_get_abs_path_safe(context, &path);
let path_abs = dc_get_abs_path(context, &path);
if let Err(_err) = fs::write(&path_abs, buf) {
warn!(
context,
@@ -953,7 +932,7 @@ pub unsafe fn dc_read_file(
}
pub fn dc_read_file_safe<P: AsRef<std::path::Path>>(context: &Context, path: P) -> Option<Vec<u8>> {
let path_abs = dc_get_abs_path_safe(context, &path);
let path_abs = dc_get_abs_path(context, &path);
match fs::read(&path_abs) {
Ok(bytes) => Some(bytes),
Err(_err) => {

View File

@@ -87,7 +87,7 @@ impl E2eeHelper {
EncryptPreference::NoPreference
};
let addr = context.sql.get_config(context, "configured_addr");
let addr = context.get_config(Config::ConfiguredAddr);
if let Some(addr) = addr {
let pubkey_ret = load_or_generate_self_public_key(context, &addr).map_err(|err| {
@@ -408,7 +408,8 @@ impl E2eeHelper {
}
}
let mut peerstate = None;
let autocryptheader = Aheader::from_imffields(from, imffields);
let autocryptheader =
as_opt_str(from).and_then(|from| Aheader::from_imffields(from, imffields));
if message_time > 0 && !from.is_null() {
peerstate = Peerstate::from_addr(context, &context.sql, as_str(from));
@@ -429,7 +430,7 @@ impl E2eeHelper {
}
}
/* load private key for decryption */
let self_addr = context.sql.get_config(context, "configured_addr");
let self_addr = context.get_config(Config::ConfiguredAddr);
if let Some(self_addr) = self_addr {
if private_keyring.load_self_private_for_decrypting(
context,

View File

@@ -182,11 +182,10 @@ impl Job {
);
let chat_id: i32 = context
.sql
.query_row_col(
.query_get_value(
context,
"SELECT chat_id FROM msgs WHERE id=?",
params![self.foreign_id as i32],
0,
)
.unwrap_or_default();
context.call_cb(
@@ -599,11 +598,10 @@ pub fn perform_smtp_idle(context: &Context) {
fn get_next_wakeup_time(context: &Context, thread: Thread) -> Duration {
let t: i64 = context
.sql
.query_row_col(
.query_get_value(
context,
"SELECT MIN(desired_timestamp) FROM jobs WHERE thread=?;",
params![thread],
0,
)
.unwrap_or_default();

View File

@@ -1,6 +1,7 @@
use std::collections::BTreeMap;
use std::ffi::{CStr, CString};
use std::io::Cursor;
use std::path::Path;
use libc;
use pgp::composed::{Deserializable, SignedPublicKey, SignedSecretKey};
@@ -142,11 +143,10 @@ impl Key {
) -> Option<Self> {
let addr = self_addr.as_ref();
sql.query_row_col(
sql.query_get_value(
context,
"SELECT public_key FROM keypairs WHERE addr=? AND is_default=1;",
&[addr],
0,
)
.and_then(|blob: Vec<u8>| Self::from_slice(&blob, KeyType::Public))
}
@@ -156,11 +156,10 @@ impl Key {
self_addr: impl AsRef<str>,
sql: &Sql,
) -> Option<Self> {
sql.query_row_col(
sql.query_get_value(
context,
"SELECT private_key FROM keypairs WHERE addr=? AND is_default=1;",
&[self_addr.as_ref()],
0,
)
.and_then(|blob: Vec<u8>| Self::from_slice(&blob, KeyType::Private))
}
@@ -218,30 +217,15 @@ impl Key {
.expect("failed to serialize key")
}
pub fn write_asc_to_file(&self, file: *const libc::c_char, context: &Context) -> bool {
if file.is_null() {
pub fn write_asc_to_file(&self, file: impl AsRef<Path>, context: &Context) -> bool {
let file_content = self.to_asc(None).into_bytes();
if dc_write_file_safe(context, &file, &file_content) {
return true;
} else {
error!(context, "Cannot write key to {}", file.as_ref().display());
return false;
}
let file_content = self.to_asc(None);
let file_content_c = CString::new(file_content).unwrap();
let success = if 0
== unsafe {
dc_write_file(
context,
file,
file_content_c.as_ptr() as *const libc::c_void,
file_content_c.as_bytes().len(),
)
} {
error!(context, "Cannot write key to {}", to_string(file));
false
} else {
true
};
success
}
pub fn fingerprint(&self) -> String {

View File

@@ -33,11 +33,10 @@ impl<'a> Keyring<'a> {
self_addr: impl AsRef<str>,
sql: &Sql,
) -> bool {
sql.query_row_col(
sql.query_get_value(
context,
"SELECT private_key FROM keypairs ORDER BY addr=? DESC, is_default DESC;",
&[self_addr.as_ref()],
0,
)
.and_then(|blob: Vec<u8>| Key::from_slice(&blob, KeyType::Private))
.map(|key| self.add_owned(key))

View File

@@ -1,5 +1,5 @@
use std::ffi::CString;
use std::path::Path;
use std::path::{Path, PathBuf};
use std::ptr;
use deltachat_derive::{FromSql, ToSql};
@@ -173,11 +173,10 @@ pub unsafe fn dc_get_msg_info(context: &Context, msg_id: u32) -> *mut libc::c_ch
let msg = msg.unwrap();
let rawtxt: Option<String> = context.sql.query_row_col(
let rawtxt: Option<String> = context.sql.query_get_value(
context,
"SELECT txt_raw FROM msgs WHERE id=?;",
params![msg_id as i32],
0,
);
if rawtxt.is_none() {
@@ -269,15 +268,10 @@ pub unsafe fn dc_get_msg_info(context: &Context, msg_id: u32) -> *mut libc::c_ch
_ => {}
}
let p = dc_msg_get_file(context, &msg);
if !p.is_null() && 0 != *p.offset(0isize) as libc::c_int {
ret += &format!(
"\nFile: {}, {}, bytes\n",
as_str(p),
dc_get_filebytes(context, as_path(p)) as libc::c_int,
);
if let Some(path) = dc_msg_get_file(context, &msg) {
let bytes = dc_get_filebytes(context, &path);
ret += &format!("\nFile: {}, {}, bytes\n", path.display(), bytes);
}
free(p as *mut libc::c_void);
if msg.type_0 != Viewtype::Text {
ret += "Type: ";
@@ -378,17 +372,10 @@ pub fn dc_msg_guess_msgtype_from_suffix(path: &Path) -> Option<(Viewtype, &str)>
KNOWN.get(extension).map(|x| *x)
}
pub unsafe fn dc_msg_get_file(context: &Context, msg: &Message) -> *mut libc::c_char {
let mut file_abs = ptr::null_mut();
if let Some(file_rel) = msg.param.get(Param::File) {
file_abs = dc_get_abs_path(context, file_rel);
}
if !file_abs.is_null() {
file_abs
} else {
dc_strdup(0 as *const libc::c_char)
}
pub unsafe fn dc_msg_get_file(context: &Context, msg: &Message) -> Option<PathBuf> {
msg.param
.get(Param::File)
.map(|f| dc_get_abs_path(context, f))
}
/**
@@ -503,11 +490,10 @@ pub fn dc_msg_load_from_db(context: &Context, id: u32) -> Result<Message, Error>
}
pub unsafe fn dc_get_mime_headers(context: &Context, msg_id: u32) -> *mut libc::c_char {
let headers: Option<String> = context.sql.query_row_col(
let headers: Option<String> = context.sql.query_get_value(
context,
"SELECT mime_headers FROM msgs WHERE id=?;",
params![msg_id as i32],
0,
);
if let Some(headers) = headers {
@@ -896,29 +882,16 @@ pub fn dc_msg_is_setupmessage(msg: &Message) -> bool {
}
pub unsafe fn dc_msg_get_setupcodebegin(context: &Context, msg: &Message) -> *mut libc::c_char {
let mut filename: *mut libc::c_char = ptr::null_mut();
let mut buf: *mut libc::c_char = ptr::null_mut();
let mut buf_bytes: size_t = 0i32 as size_t;
// just a pointer inside buf, MUST NOT be free()'d
let mut buf_headerline: *const libc::c_char = ptr::null();
// just a pointer inside buf, MUST NOT be free()'d
let mut buf_setupcodebegin: *const libc::c_char = ptr::null();
let mut ret: *mut libc::c_char = ptr::null_mut();
if dc_msg_is_setupmessage(msg) {
filename = dc_msg_get_file(context, msg);
if !(filename.is_null() || *filename.offset(0isize) as libc::c_int == 0i32) {
if !(0
== dc_read_file(
context,
filename,
&mut buf as *mut *mut libc::c_char as *mut *mut libc::c_void,
&mut buf_bytes,
)
|| buf.is_null()
|| buf_bytes <= 0)
{
if let Some(filename) = dc_msg_get_file(context, msg) {
if let Some(mut buf) = dc_read_file_safe(context, filename) {
if dc_split_armored_data(
buf,
buf.as_mut_ptr().cast(),
&mut buf_headerline,
&mut buf_setupcodebegin,
ptr::null_mut(),
@@ -934,8 +907,6 @@ pub unsafe fn dc_msg_get_setupcodebegin(context: &Context, msg: &Message) -> *mu
}
}
}
free(filename as *mut libc::c_void);
free(buf as *mut libc::c_void);
if !ret.is_null() {
ret
} else {
@@ -1035,11 +1006,10 @@ pub fn dc_msg_exists(context: &Context, msg_id: u32) -> bool {
return false;
}
let chat_id: Option<u32> = context.sql.query_row_col(
let chat_id: Option<u32> = context.sql.query_get_value(
context,
"SELECT chat_id FROM msgs WHERE id=?;",
params![msg_id],
0,
);
if let Some(chat_id) = chat_id {
@@ -1158,11 +1128,10 @@ pub unsafe fn dc_mdn_from_ext(
/* send event about new state */
let ist_cnt: i32 = context
.sql
.query_row_col(
.query_get_value(
context,
"SELECT COUNT(*) FROM msgs_mdns WHERE msg_id=?;",
params![*ret_msg_id as i32],
0,
)
.unwrap_or_default();
/*

View File

@@ -4,6 +4,7 @@ use std::ptr;
use crate::aheader::EncryptPreference;
use crate::chat::{self, Chat};
use crate::config::*;
use crate::configure::*;
use crate::constants::*;
use crate::contact::*;
@@ -82,7 +83,7 @@ pub fn dc_get_securejoin_qr(context: &Context, group_chat_id: uint32_t) -> Optio
ensure_secret_key_exists(context).ok();
let invitenumber = token::lookup_or_new(context, token::Namespace::InviteNumber, group_chat_id);
let auth = token::lookup_or_new(context, token::Namespace::Auth, group_chat_id);
let self_addr = match context.sql.get_config(context, "configured_addr") {
let self_addr = match context.get_config(Config::ConfiguredAddr) {
Some(addr) => addr,
None => {
error!(context, "Not configured, cannot generate QR code.",);
@@ -139,7 +140,7 @@ pub fn dc_get_securejoin_qr(context: &Context, group_chat_id: uint32_t) -> Optio
}
fn get_self_fingerprint(context: &Context) -> Option<String> {
if let Some(self_addr) = context.sql.get_config(context, "configured_addr") {
if let Some(self_addr) = context.get_config(Config::ConfiguredAddr) {
if let Some(key) = Key::from_self_public(context, self_addr, &context.sql) {
return Some(key.fingerprint());
}
@@ -753,11 +754,10 @@ pub fn handle_degrade_event(context: &Context, peerstate: &Peerstate) {
if Some(DegradeEvent::FingerprintChanged) == peerstate.degrade_event {
let contact_id: i32 = context
.sql
.query_row_col(
.query_get_value(
context,
"SELECT id FROM contacts WHERE addr=?;",
params![&peerstate.addr],
0,
)
.unwrap_or_default();
if contact_id > 0 {

View File

@@ -155,19 +155,13 @@ impl Sql {
.unwrap_or_default()
}
pub fn query_row_col<P, T>(
&self,
context: &Context,
query: &str,
params: P,
column: usize,
) -> Option<T>
pub fn query_get_value<P, T>(&self, context: &Context, query: &str, params: P) -> Option<T>
where
P: IntoIterator,
P::Item: rusqlite::ToSql,
T: rusqlite::types::FromSql,
{
match self.query_row(query, params, |row| row.get::<_, T>(column)) {
match self.query_row(query, params, |row| row.get::<_, T>(0)) {
Ok(res) => Some(res),
Err(Error::Sql(rusqlite::Error::QueryReturnedNoRows)) => None,
Err(Error::Sql(rusqlite::Error::InvalidColumnType(
@@ -238,11 +232,10 @@ impl Sql {
if !self.is_open() || key.as_ref().is_empty() {
return None;
}
self.query_row_col(
self.query_get_value(
context,
"SELECT value FROM config WHERE keyname=?;",
params![key.as_ref()],
0,
)
}

View File

@@ -35,11 +35,10 @@ pub fn save(context: &Context, namespace: Namespace, foreign_id: u32) -> String
}
pub fn lookup(context: &Context, namespace: Namespace, foreign_id: u32) -> Option<String> {
context.sql.query_row_col::<_, String>(
context.sql.query_get_value::<_, String>(
context,
"SELECT token FROM tokens WHERE namespc=? AND foreign_id=?;",
params![namespace, foreign_id as i32],
0,
)
}