From da256117584786c92f845bd3a0b9811013bd78b4 Mon Sep 17 00:00:00 2001 From: Dmitry Bogatov Date: Fri, 6 Sep 2019 03:05:12 +0000 Subject: [PATCH 01/19] Change type of function from `const char *' to &str --- src/dc_mimeparser.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/dc_mimeparser.rs b/src/dc_mimeparser.rs index f2d662571..3920fbe55 100644 --- a/src/dc_mimeparser.rs +++ b/src/dc_mimeparser.rs @@ -1284,7 +1284,7 @@ unsafe fn dc_mimeparser_add_single_part_if_known( mimeparser, msg_type, mime_type, - raw_mime, + as_str(raw_mime), decoded_data, decoded_data_bytes, desired_filename, @@ -1312,7 +1312,7 @@ unsafe fn do_add_single_file_part( parser: &mut dc_mimeparser_t, msg_type: Viewtype, mime_type: libc::c_int, - raw_mime: *const libc::c_char, + raw_mime: &str, decoded_data: *const libc::c_char, decoded_data_bytes: size_t, desired_filename: *const libc::c_char, @@ -1338,7 +1338,7 @@ unsafe fn do_add_single_file_part( part.int_mimetype = mime_type; part.bytes = decoded_data_bytes as libc::c_int; part.param.set(Param::File, as_str(pathNfilename)); - part.param.set(Param::MimeType, as_str(raw_mime)); + part.param.set(Param::MimeType, raw_mime); if mime_type == 80 { assert!(!decoded_data.is_null(), "invalid image data"); let data = std::slice::from_raw_parts( From 4d8b058b65187bc872dd593f1d75be11ec89771c Mon Sep 17 00:00:00 2001 From: Dmitry Bogatov Date: Fri, 6 Sep 2019 03:36:54 +0000 Subject: [PATCH 02/19] Change type of dc_mimeparser_t.is_forwarded to bool --- src/dc_mimeparser.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/dc_mimeparser.rs b/src/dc_mimeparser.rs index 3920fbe55..4dee953f0 100644 --- a/src/dc_mimeparser.rs +++ b/src/dc_mimeparser.rs @@ -54,7 +54,7 @@ pub struct dc_mimeparser_t<'a> { pub is_send_by_messenger: bool, pub decrypting_failed: libc::c_int, pub e2ee_helper: E2eeHelper, - pub is_forwarded: libc::c_int, + pub is_forwarded: bool, pub context: &'a Context, pub reports: Vec<*mut mailmime>, pub is_system_message: libc::c_int, @@ -73,7 +73,7 @@ pub fn dc_mimeparser_new(context: &Context) -> dc_mimeparser_t { is_send_by_messenger: false, decrypting_failed: 0, e2ee_helper: Default::default(), - is_forwarded: 0, + is_forwarded: false, context, reports: Vec::new(), is_system_message: 0, @@ -105,7 +105,7 @@ unsafe fn dc_mimeparser_empty(mimeparser: &mut dc_mimeparser_t) { mailmime_free(mimeparser.mimeroot); mimeparser.mimeroot = ptr::null_mut() } - mimeparser.is_forwarded = 0i32; + mimeparser.is_forwarded = false; mimeparser.reports.clear(); mimeparser.decrypting_failed = 0i32; mimeparser.e2ee_helper.thanks(); @@ -273,7 +273,7 @@ pub unsafe fn dc_mimeparser_parse<'a>(context: &'a Context, body: &[u8]) -> dc_m free(subj as *mut libc::c_void); } } - if 0 != mimeparser.is_forwarded { + if mimeparser.is_forwarded { for part in mimeparser.parts.iter_mut() { part.param.set_int(Param::Forwarded, 1); } @@ -1130,7 +1130,7 @@ unsafe fn dc_mimeparser_add_single_part_if_known( } if simplifier.unwrap().is_forwarded { - mimeparser.is_forwarded = 1i32 + mimeparser.is_forwarded = true; } } } From e0df78c5f7bc141881a2ff5964ebc0d550971b4d Mon Sep 17 00:00:00 2001 From: Dmitry Bogatov Date: Fri, 6 Sep 2019 03:39:44 +0000 Subject: [PATCH 03/19] Change type of dc_mimepart_t.is_meta to bool --- src/dc_mimeparser.rs | 14 +++++--------- src/dc_receive_imf.rs | 2 +- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/src/dc_mimeparser.rs b/src/dc_mimeparser.rs index 4dee953f0..ef1624df8 100644 --- a/src/dc_mimeparser.rs +++ b/src/dc_mimeparser.rs @@ -32,7 +32,7 @@ dc_mimeparser_t has no deep dependencies to Context or to the database #[repr(C)] pub struct dc_mimepart_t { pub type_0: Viewtype, - pub is_meta: libc::c_int, + pub is_meta: bool, pub int_mimetype: libc::c_int, pub msg: Option, pub msg_raw: *mut libc::c_char, @@ -196,7 +196,7 @@ pub unsafe fn dc_mimeparser_parse<'a>(context: &'a Context, body: &[u8]) -> dc_m if mimeparser.parts.len() >= 2 { let imgpart = &mut mimeparser.parts[1]; if imgpart.type_0 == Viewtype::Image { - imgpart.is_meta = 1i32 + imgpart.is_meta = true; } } } @@ -212,7 +212,7 @@ pub unsafe fn dc_mimeparser_parse<'a>(context: &'a Context, body: &[u8]) -> dc_m || filepart.type_0 == Viewtype::Voice || filepart.type_0 == Viewtype::Video || filepart.type_0 == Viewtype::File) - && 0 == filepart.is_meta + && !filepart.is_meta }; if need_drop { @@ -366,7 +366,7 @@ pub unsafe fn dc_mimeparser_parse<'a>(context: &'a Context, body: &[u8]) -> dc_m unsafe fn dc_mimepart_new() -> dc_mimepart_t { dc_mimepart_t { type_0: Viewtype::Unknown, - is_meta: 0, + is_meta: false, int_mimetype: 0, msg: None, msg_raw: std::ptr::null_mut(), @@ -378,11 +378,7 @@ unsafe fn dc_mimepart_new() -> dc_mimepart_t { pub fn dc_mimeparser_get_last_nonmeta<'a>( mimeparser: &'a mut dc_mimeparser_t, ) -> Option<&'a mut dc_mimepart_t> { - mimeparser - .parts - .iter_mut() - .rev() - .find(|part| part.is_meta == 0) + mimeparser.parts.iter_mut().rev().find(|part| !part.is_meta) } /*the result must be freed*/ diff --git a/src/dc_receive_imf.rs b/src/dc_receive_imf.rs index e4f0e65c4..378966810 100644 --- a/src/dc_receive_imf.rs +++ b/src/dc_receive_imf.rs @@ -625,7 +625,7 @@ unsafe fn add_parts( |mut stmt, conn| { for i in 0..icnt { let part = &mut mime_parser.parts[i]; - if part.is_meta != 0 { + if part.is_meta { continue; } From 28cfe36f4328eb4ccf920b13efea088af1c0cf8b Mon Sep 17 00:00:00 2001 From: Dmitry Bogatov Date: Fri, 6 Sep 2019 03:48:41 +0000 Subject: [PATCH 04/19] Change type of dc_mimeparser_t.decryption_failed to bool --- src/dc_mimeparser.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/dc_mimeparser.rs b/src/dc_mimeparser.rs index ef1624df8..790deb257 100644 --- a/src/dc_mimeparser.rs +++ b/src/dc_mimeparser.rs @@ -52,7 +52,7 @@ pub struct dc_mimeparser_t<'a> { pub header_protected: *mut mailimf_fields, pub subject: *mut libc::c_char, pub is_send_by_messenger: bool, - pub decrypting_failed: libc::c_int, + pub decrypting_failed: bool, pub e2ee_helper: E2eeHelper, pub is_forwarded: bool, pub context: &'a Context, @@ -71,7 +71,7 @@ pub fn dc_mimeparser_new(context: &Context) -> dc_mimeparser_t { header_protected: std::ptr::null_mut(), subject: std::ptr::null_mut(), is_send_by_messenger: false, - decrypting_failed: 0, + decrypting_failed: false, e2ee_helper: Default::default(), is_forwarded: false, context, @@ -107,7 +107,7 @@ unsafe fn dc_mimeparser_empty(mimeparser: &mut dc_mimeparser_t) { } mimeparser.is_forwarded = false; mimeparser.reports.clear(); - mimeparser.decrypting_failed = 0i32; + mimeparser.decrypting_failed = false; mimeparser.e2ee_helper.thanks(); mimeparser.location_kml = None; @@ -233,7 +233,7 @@ pub unsafe fn dc_mimeparser_parse<'a>(context: &'a Context, body: &[u8]) -> dc_m } if !mimeparser.subject.is_null() { let mut prepend_subject: libc::c_int = 1i32; - if 0 == mimeparser.decrypting_failed { + if !mimeparser.decrypting_failed { let p: *mut libc::c_char = strchr(mimeparser.subject, ':' as i32); if p.wrapping_offset_from(mimeparser.subject) == 2 || p.wrapping_offset_from(mimeparser.subject) == 3 @@ -301,7 +301,7 @@ pub unsafe fn dc_mimeparser_parse<'a>(context: &'a Context, body: &[u8]) -> dc_m } } } - if 0 == mimeparser.decrypting_failed { + if !mimeparser.decrypting_failed { let dn_field: *const mailimf_optional_field = dc_mimeparser_lookup_optional_field( &mimeparser, "Chat-Disposition-Notification-To", @@ -597,7 +597,7 @@ unsafe fn dc_mimeparser_parse_mime_recursive( mimeparser.parts.push(part); any_part_added = 1i32; - mimeparser.decrypting_failed = 1i32 + mimeparser.decrypting_failed = true; } 46 => { cur = (*(*mime).mm_data.mm_multipart.mm_mp_list).first; From 1d75f8478ce6cbd2c5482fb5da920eafdf2bee24 Mon Sep 17 00:00:00 2001 From: Dmitry Bogatov Date: Fri, 6 Sep 2019 04:06:40 +0000 Subject: [PATCH 05/19] Rustify type of dc_mimepart_t.msg_raw --- src/dc_mimeparser.rs | 18 +++++++++++------- src/dc_receive_imf.rs | 4 +++- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/src/dc_mimeparser.rs b/src/dc_mimeparser.rs index 790deb257..75abd2b91 100644 --- a/src/dc_mimeparser.rs +++ b/src/dc_mimeparser.rs @@ -35,7 +35,7 @@ pub struct dc_mimepart_t { pub is_meta: bool, pub int_mimetype: libc::c_int, pub msg: Option, - pub msg_raw: *mut libc::c_char, + pub msg_raw: Option, pub bytes: libc::c_int, pub param: Params, } @@ -116,8 +116,7 @@ unsafe fn dc_mimeparser_empty(mimeparser: &mut dc_mimeparser_t) { unsafe fn dc_mimepart_unref(mut mimepart: dc_mimepart_t) { mimepart.msg = None; - free(mimepart.msg_raw as *mut libc::c_void); - mimepart.msg_raw = ptr::null_mut(); + mimepart.msg_raw = None; } const DC_MIMETYPE_AC_SETUP_FILE: i32 = 111; @@ -369,7 +368,7 @@ unsafe fn dc_mimepart_new() -> dc_mimepart_t { is_meta: false, int_mimetype: 0, msg: None, - msg_raw: std::ptr::null_mut(), + msg_raw: None, bytes: 0, param: Params::new(), } @@ -592,7 +591,7 @@ unsafe fn dc_mimeparser_parse_mime_recursive( .stock_str(StockMessage::CantDecryptMsgBody); let txt = format!("[{}]", msg_body); - part.msg_raw = txt.strdup(); + part.msg_raw = Some(txt.clone()); part.msg = Some(txt); mimeparser.parts.push(part); @@ -1120,8 +1119,13 @@ unsafe fn dc_mimeparser_add_single_part_if_known( part.type_0 = Viewtype::Text; part.int_mimetype = mime_type; part.msg = Some(simplified_txt); - part.msg_raw = - strndup(decoded_data, decoded_data_bytes as libc::c_ulong); + part.msg_raw = { + let raw_c = + strndup(decoded_data, decoded_data_bytes as libc::c_ulong); + let raw = to_string(raw_c); + free(raw_c.cast()); + Some(raw) + }; do_add_single_part(mimeparser, part); } diff --git a/src/dc_receive_imf.rs b/src/dc_receive_imf.rs index 378966810..c3a0b34e8 100644 --- a/src/dc_receive_imf.rs +++ b/src/dc_receive_imf.rs @@ -1,3 +1,4 @@ +use std::ffi::CString; use std::ptr; use itertools::join; @@ -641,6 +642,7 @@ unsafe fn add_parts( } } if part.type_0 == Viewtype::Text { + let msg_raw = CString::yolo(part.msg_raw.as_ref().unwrap().clone()); txt_raw = dc_mprintf( b"%s\n\n%s\x00" as *const u8 as *const libc::c_char, if !mime_parser.subject.is_null() { @@ -648,7 +650,7 @@ unsafe fn add_parts( } else { b"\x00" as *const u8 as *const libc::c_char }, - part.msg_raw, + msg_raw.as_ptr(), ) } if 0 != mime_parser.is_system_message { From 743e4deb36d23cad45aaf89d7bf0bc810b786ab5 Mon Sep 17 00:00:00 2001 From: Dmitry Bogatov Date: Fri, 6 Sep 2019 05:18:46 +0000 Subject: [PATCH 06/19] Remove dc_mimepart_unref function Since there is no longer any manually-managed memory, associated with `dc_mimepart_t' structure, default Drop instances does everything automatically. --- src/dc_mimeparser.rs | 21 ++++----------------- 1 file changed, 4 insertions(+), 17 deletions(-) diff --git a/src/dc_mimeparser.rs b/src/dc_mimeparser.rs index 75abd2b91..fc9f9b3cd 100644 --- a/src/dc_mimeparser.rs +++ b/src/dc_mimeparser.rs @@ -87,10 +87,7 @@ pub unsafe fn dc_mimeparser_unref(mimeparser: &mut dc_mimeparser_t) { } unsafe fn dc_mimeparser_empty(mimeparser: &mut dc_mimeparser_t) { - for part in mimeparser.parts.drain(..) { - dc_mimepart_unref(part); - } - assert!(mimeparser.parts.is_empty()); + mimeparser.parts = vec![]; mimeparser.header_root = ptr::null_mut(); mimeparser.header.clear(); if !mimeparser.header_protected.is_null() { @@ -114,10 +111,6 @@ unsafe fn dc_mimeparser_empty(mimeparser: &mut dc_mimeparser_t) { mimeparser.message_kml = None; } -unsafe fn dc_mimepart_unref(mut mimepart: dc_mimepart_t) { - mimepart.msg = None; - mimepart.msg_raw = None; -} const DC_MIMETYPE_AC_SETUP_FILE: i32 = 111; pub unsafe fn dc_mimeparser_parse<'a>(context: &'a Context, body: &[u8]) -> dc_mimeparser_t<'a> { @@ -168,8 +161,7 @@ pub unsafe fn dc_mimeparser_parse<'a>(context: &'a Context, body: &[u8]) -> dc_m let mut i = 0; while i != mimeparser.parts.len() { if mimeparser.parts[i].int_mimetype != 111 { - let part = mimeparser.parts.remove(i); - dc_mimepart_unref(part); + mimeparser.parts.remove(i); } else { i += 1; } @@ -224,10 +216,7 @@ pub unsafe fn dc_mimeparser_parse<'a>(context: &'a Context, body: &[u8]) -> dc_m mimeparser.parts[0].msg = None; // swap new with old - let old = std::mem::replace(&mut mimeparser.parts[0], filepart); - - // unref old one - dc_mimepart_unref(old); + std::mem::replace(&mut mimeparser.parts[0], filepart); } } if !mimeparser.subject.is_null() { @@ -1655,9 +1644,7 @@ pub unsafe fn dc_mimeparser_repl_msg_by_error( let part = &mut mimeparser.parts[0]; part.type_0 = Viewtype::Text; part.msg = Some(format!("[{}]", to_string(error_msg))); - for part in mimeparser.parts.drain(1..) { - dc_mimepart_unref(part); - } + mimeparser.parts.truncate(1); assert_eq!(mimeparser.parts.len(), 1); } From a4e4b0fc171672a67c7f2105238e481c0d213c46 Mon Sep 17 00:00:00 2001 From: Dmitry Bogatov Date: Fri, 6 Sep 2019 06:14:27 +0000 Subject: [PATCH 07/19] Rustify type of dc_mimeparser_t.subject --- src/dc_mimeparser.rs | 63 ++++++++++++++++++++++--------------------- src/dc_receive_imf.rs | 17 +++++++----- 2 files changed, 43 insertions(+), 37 deletions(-) diff --git a/src/dc_mimeparser.rs b/src/dc_mimeparser.rs index fc9f9b3cd..cf99d24d2 100644 --- a/src/dc_mimeparser.rs +++ b/src/dc_mimeparser.rs @@ -50,7 +50,7 @@ pub struct dc_mimeparser_t<'a> { pub header: HashMap, pub header_root: *mut mailimf_fields, pub header_protected: *mut mailimf_fields, - pub subject: *mut libc::c_char, + pub subject: Option, pub is_send_by_messenger: bool, pub decrypting_failed: bool, pub e2ee_helper: E2eeHelper, @@ -69,7 +69,7 @@ pub fn dc_mimeparser_new(context: &Context) -> dc_mimeparser_t { header: Default::default(), header_root: std::ptr::null_mut(), header_protected: std::ptr::null_mut(), - subject: std::ptr::null_mut(), + subject: None, is_send_by_messenger: false, decrypting_failed: false, e2ee_helper: Default::default(), @@ -96,8 +96,7 @@ unsafe fn dc_mimeparser_empty(mimeparser: &mut dc_mimeparser_t) { } mimeparser.is_send_by_messenger = false; mimeparser.is_system_message = 0i32; - free(mimeparser.subject as *mut libc::c_void); - mimeparser.subject = ptr::null_mut(); + mimeparser.subject = None; if !mimeparser.mimeroot.is_null() { mailmime_free(mimeparser.mimeroot); mimeparser.mimeroot = ptr::null_mut() @@ -133,7 +132,15 @@ pub unsafe fn dc_mimeparser_parse<'a>(context: &'a Context, body: &[u8]) -> dc_m dc_mimeparser_parse_mime_recursive(mimeparser_ref, mimeparser_ref.mimeroot); let field: *mut mailimf_field = dc_mimeparser_lookup_field(&mimeparser, "Subject"); if !field.is_null() && (*field).fld_type == MAILIMF_FIELD_SUBJECT as libc::c_int { - mimeparser.subject = dc_decode_header_words((*(*field).fld_data.fld_subject).sbj_value) + let decoded = dc_decode_header_words((*(*field).fld_data.fld_subject).sbj_value); + if decoded.is_null() + /* XXX: can it happen? */ + { + mimeparser.subject = None + } else { + mimeparser.subject = Some(to_string(decoded)); + free(decoded.cast()); + } } if !dc_mimeparser_lookup_optional_field(&mut mimeparser, "Chat-Version").is_null() { mimeparser.is_send_by_messenger = true @@ -219,36 +226,34 @@ pub unsafe fn dc_mimeparser_parse<'a>(context: &'a Context, body: &[u8]) -> dc_m std::mem::replace(&mut mimeparser.parts[0], filepart); } } - if !mimeparser.subject.is_null() { + if let Some(ref subject) = mimeparser.subject { let mut prepend_subject: libc::c_int = 1i32; if !mimeparser.decrypting_failed { - let p: *mut libc::c_char = strchr(mimeparser.subject, ':' as i32); - if p.wrapping_offset_from(mimeparser.subject) == 2 - || p.wrapping_offset_from(mimeparser.subject) == 3 + let colon = subject.find(':'); + if colon == Some(2) + || colon == Some(3) || mimeparser.is_send_by_messenger - || !strstr( - mimeparser.subject, - b"Chat:\x00" as *const u8 as *const libc::c_char, - ) - .is_null() + || subject.contains("Chat:") { prepend_subject = 0i32 } } if 0 != prepend_subject { - let subj: *mut libc::c_char = dc_strdup(mimeparser.subject); - let p_0: *mut libc::c_char = strchr(subj, '[' as i32); - if !p_0.is_null() { - *p_0 = 0i32 as libc::c_char + let subj = if let Some(n) = subject.find('[') { + &subject[0..n] + } else { + subject } - dc_trim(subj); - if 0 != *subj.offset(0isize) { + .trim(); + + if !subj.is_empty() { + let subj_c = CString::yolo(subj); for part in mimeparser.parts.iter_mut() { if part.type_0 == Viewtype::Text { let msg_c = part.msg.as_ref().unwrap().strdup(); let new_txt: *mut libc::c_char = dc_mprintf( b"%s \xe2\x80\x93 %s\x00" as *const u8 as *const libc::c_char, - subj, + subj_c.as_ptr(), msg_c, ); free(msg_c.cast()); @@ -258,7 +263,6 @@ pub unsafe fn dc_mimeparser_parse<'a>(context: &'a Context, body: &[u8]) -> dc_m } } } - free(subj as *mut libc::c_void); } } if mimeparser.is_forwarded { @@ -338,10 +342,12 @@ pub unsafe fn dc_mimeparser_parse<'a>(context: &'a Context, body: &[u8]) -> dc_m if dc_mimeparser_get_last_nonmeta(&mut mimeparser).is_none() && mimeparser.reports.is_empty() { let mut part_5 = dc_mimepart_new(); part_5.type_0 = Viewtype::Text; - if !mimeparser.subject.is_null() && !mimeparser.is_send_by_messenger { - part_5.msg = Some(to_string(mimeparser.subject)); - } else { - part_5.msg = Some("".into()); + part_5.msg = Some("".into()); + + if let Some(ref subject) = mimeparser.subject { + if !mimeparser.is_send_by_messenger { + part_5.msg = Some(subject.to_string()) + } } mimeparser.parts.push(part_5); }; @@ -1801,10 +1807,7 @@ mod tests { let raw = b"Content-Type: multipart/mixed; boundary=\"==break==\";\nSubject: outer-subject\nX-Special-A: special-a\nFoo: Bar\nChat-Version: 0.0\n\n--==break==\nContent-Type: text/plain; protected-headers=\"v1\";\nSubject: inner-subject\nX-Special-B: special-b\nFoo: Xy\nChat-Version: 1.0\n\ntest1\n\n--==break==--\n\n\x00"; let mut mimeparser = dc_mimeparser_parse(&context.ctx, &raw[..]); - assert_eq!( - &to_string(mimeparser.subject as *const libc::c_char), - "inner-subject", - ); + assert_eq!(mimeparser.subject, Some("inner-subject".into())); let mut of: *mut mailimf_optional_field = dc_mimeparser_lookup_optional_field(&mimeparser, "X-Special-A"); diff --git a/src/dc_receive_imf.rs b/src/dc_receive_imf.rs index c3a0b34e8..29bfdd2f9 100644 --- a/src/dc_receive_imf.rs +++ b/src/dc_receive_imf.rs @@ -643,13 +643,16 @@ unsafe fn add_parts( } if part.type_0 == Viewtype::Text { let msg_raw = CString::yolo(part.msg_raw.as_ref().unwrap().clone()); + let subject_c = CString::yolo( + mime_parser + .subject + .as_ref() + .map(|s| s.to_string()) + .unwrap_or("".into()), + ); txt_raw = dc_mprintf( b"%s\n\n%s\x00" as *const u8 as *const libc::c_char, - if !mime_parser.subject.is_null() { - mime_parser.subject - } else { - b"\x00" as *const u8 as *const libc::c_char - }, + subject_c.as_ptr(), msg_raw.as_ptr(), ) } @@ -1570,8 +1573,8 @@ unsafe fn create_or_lookup_adhoc_group( } // use subject as initial chat name - if !mime_parser.subject.is_null() && 0 != *mime_parser.subject.offset(0isize) as libc::c_int { - grpname = dc_strdup(mime_parser.subject) + if let Some(subject) = mime_parser.subject.as_ref().filter(|s| !s.is_empty()) { + grpname = subject.strdup(); } else { grpname = context .stock_string_repl_int(StockMessage::Member, member_ids.len() as libc::c_int) From dc1839760cd6ec8b5b4efe78a9f9ebf63184bec9 Mon Sep 17 00:00:00 2001 From: Dmitry Bogatov Date: Fri, 6 Sep 2019 13:02:28 +0000 Subject: [PATCH 08/19] Simplify clist_search_string_nocase using Iterator interface --- src/dc_tools.rs | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/src/dc_tools.rs b/src/dc_tools.rs index 7a5578141..c2b0bc7ef 100644 --- a/src/dc_tools.rs +++ b/src/dc_tools.rs @@ -436,19 +436,11 @@ pub unsafe fn clist_search_string_nocase( haystack: *const clist, needle: *const libc::c_char, ) -> libc::c_int { - let mut iter = (*haystack).first; - - while !iter.is_null() { - if strcasecmp((*iter).data as *const libc::c_char, needle) == 0 { + for data in &*haystack { + if strcasecmp(data.cast(), needle) == 0 { return 1; } - iter = if !iter.is_null() { - (*iter).next - } else { - ptr::null_mut() - } } - 0 } From c0e729336040d89fcdce607b6367e48ede492259 Mon Sep 17 00:00:00 2001 From: Dmitry Bogatov Date: Fri, 6 Sep 2019 13:08:52 +0000 Subject: [PATCH 09/19] Change return type of clist_search_string_nocase to `bool' --- src/dc_mimefactory.rs | 4 ++-- src/dc_tools.rs | 11 ++++------- src/job.rs | 4 +--- 3 files changed, 7 insertions(+), 12 deletions(-) diff --git a/src/dc_mimefactory.rs b/src/dc_mimefactory.rs index cf9e095a0..e15a3a5e9 100644 --- a/src/dc_mimefactory.rs +++ b/src/dc_mimefactory.rs @@ -148,7 +148,7 @@ pub unsafe fn dc_mimefactory_load_msg( for row in rows { let (authname, addr) = row?; let addr_c = addr.strdup(); - if clist_search_string_nocase(factory.recipients_addr, addr_c) == 0 { + if !clist_search_string_nocase(factory.recipients_addr, addr_c) { clist_insert_after( factory.recipients_names, (*factory.recipients_names).last, @@ -183,7 +183,7 @@ pub unsafe fn dc_mimefactory_load_msg( .unwrap_or_default(); if !email_to_remove.is_empty() && email_to_remove != self_addr { - if clist_search_string_nocase(factory.recipients_addr, email_to_remove_c) == 0 { + if !clist_search_string_nocase(factory.recipients_addr, email_to_remove_c) { clist_insert_after( factory.recipients_names, (*factory.recipients_names).last, diff --git a/src/dc_tools.rs b/src/dc_tools.rs index c2b0bc7ef..6fa6135e0 100644 --- a/src/dc_tools.rs +++ b/src/dc_tools.rs @@ -435,13 +435,10 @@ pub unsafe fn clist_free_content(haystack: *const clist) { pub unsafe fn clist_search_string_nocase( haystack: *const clist, needle: *const libc::c_char, -) -> libc::c_int { - for data in &*haystack { - if strcasecmp(data.cast(), needle) == 0 { - return 1; - } - } - 0 +) -> bool { + (&*haystack) + .into_iter() + .any(|data| strcasecmp(data.cast(), needle) == 0) } /* date/time tools */ diff --git a/src/job.rs b/src/job.rs index bacb73c1b..066e0eac4 100644 --- a/src/job.rs +++ b/src/job.rs @@ -692,9 +692,7 @@ pub unsafe fn job_send_msg(context: &Context, msg_id: uint32_t) -> libc::c_int { ); } else { /* unrecoverable */ - if clist_search_string_nocase(mimefactory.recipients_addr, mimefactory.from_addr) - == 0i32 - { + if !clist_search_string_nocase(mimefactory.recipients_addr, mimefactory.from_addr) { clist_insert_after( mimefactory.recipients_names, (*mimefactory.recipients_names).last, From 3a57ba1142fe5952d1f892f072066b8c79f07486 Mon Sep 17 00:00:00 2001 From: Dmitry Bogatov Date: Fri, 6 Sep 2019 22:36:34 +0000 Subject: [PATCH 10/19] Implement safe version of `get_parent_mime_headers' function --- src/chat.rs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/chat.rs b/src/chat.rs index 908b879fc..ea58b70e4 100644 --- a/src/chat.rs +++ b/src/chat.rs @@ -218,6 +218,22 @@ impl<'a> Chat<'a> { Ok(()) } + pub fn get_parent_mime_headers_safe(&self) -> Option<(String, String, String)> { + let collect = |row: &rusqlite::Row| Ok((row.get(0)?, row.get(1)?, row.get(2)?)); + let params = params![self.id as i32, DC_CONTACT_ID_SELF as i32]; + let sql = &self.context.sql; + let main_query = "SELECT rfc724_mid, mime_in_reply_to, mime_references \ + FROM msgs WHERE chat_id=?1 AND timestamp=(SELECT max(timestamp) \ + FROM msgs WHERE chat_id=?1 AND from_id!=?2);"; + let fallback_query = "SELECT rfc724_mid, mime_in_reply_to, mime_references \ + FROM msgs WHERE chat_id=?1 AND timestamp=(SELECT min(timestamp) \ + FROM msgs WHERE chat_id=?1 AND from_id==?2);"; + + sql.query_row(main_query, params, collect) + .or_else(|_| sql.query_row(fallback_query, params, collect)) + .ok() + } + pub unsafe fn get_profile_image(&self) -> Option { if let Some(image_rel) = self.param.get(Param::ProfileImage) { if !image_rel.is_empty() { From aa5304a4f35a7508d16dff04daaa3422667f452a Mon Sep 17 00:00:00 2001 From: Dmitry Bogatov Date: Fri, 6 Sep 2019 23:09:52 +0000 Subject: [PATCH 11/19] Use safe version of `get_parent_mime_headers()' function --- src/chat.rs | 103 +++++++++++++++++++++++++--------------------------- 1 file changed, 50 insertions(+), 53 deletions(-) diff --git a/src/chat.rs b/src/chat.rs index ea58b70e4..5f5e1ede0 100644 --- a/src/chat.rs +++ b/src/chat.rs @@ -294,9 +294,6 @@ impl<'a> Chat<'a> { let mut do_guarantee_e2ee: libc::c_int; let e2ee_enabled: libc::c_int; let mut OK_TO_CONTINUE = true; - let mut parent_rfc724_mid = ptr::null_mut(); - let mut parent_references = ptr::null_mut(); - let mut parent_in_reply_to = ptr::null_mut(); let mut new_rfc724_mid = ptr::null_mut(); let mut new_references = ptr::null_mut(); let mut new_in_reply_to = ptr::null_mut(); @@ -421,55 +418,58 @@ impl<'a> Chat<'a> { msg.param.set_int(Param::GuranteeE2ee, 1); } msg.param.remove(Param::ErroneousE2ee); - if !self.is_self_talk() - && self - .get_parent_mime_headers( - &mut parent_rfc724_mid, - &mut parent_in_reply_to, - &mut parent_references, - ) - .is_ok() - { - if !parent_rfc724_mid.is_null() - && 0 != *parent_rfc724_mid.offset(0isize) as libc::c_int + if !self.is_self_talk() { + if let Some((parent_rfc724_mid, parent_in_reply_to, parent_references)) = + self.get_parent_mime_headers_safe() { - new_in_reply_to = dc_strdup(parent_rfc724_mid) - } - if !parent_references.is_null() { - let space: *mut libc::c_char; - space = strchr(parent_references, ' ' as i32); - if !space.is_null() { - *space = 0 as libc::c_char + let parent_rfc724_mid = parent_rfc724_mid.strdup(); + let parent_in_reply_to = parent_in_reply_to.strdup(); + let parent_references = parent_references.strdup(); + + if !parent_rfc724_mid.is_null() + && 0 != *parent_rfc724_mid.offset(0isize) as libc::c_int + { + new_in_reply_to = dc_strdup(parent_rfc724_mid) } - } - if !parent_references.is_null() - && 0 != *parent_references.offset(0isize) as libc::c_int - && !parent_rfc724_mid.is_null() - && 0 != *parent_rfc724_mid.offset(0isize) as libc::c_int - { - new_references = dc_mprintf( - b"%s %s\x00" as *const u8 as *const libc::c_char, - parent_references, - parent_rfc724_mid, - ) - } else if !parent_references.is_null() - && 0 != *parent_references.offset(0isize) as libc::c_int - { - new_references = dc_strdup(parent_references) - } else if !parent_in_reply_to.is_null() - && 0 != *parent_in_reply_to.offset(0isize) as libc::c_int - && !parent_rfc724_mid.is_null() - && 0 != *parent_rfc724_mid.offset(0isize) as libc::c_int - { - new_references = dc_mprintf( - b"%s %s\x00" as *const u8 as *const libc::c_char, - parent_in_reply_to, - parent_rfc724_mid, - ) - } else if !parent_in_reply_to.is_null() - && 0 != *parent_in_reply_to.offset(0isize) as libc::c_int - { - new_references = dc_strdup(parent_in_reply_to) + if !parent_references.is_null() { + let space: *mut libc::c_char; + space = strchr(parent_references, ' ' as i32); + if !space.is_null() { + *space = 0 as libc::c_char + } + } + if !parent_references.is_null() + && 0 != *parent_references.offset(0isize) as libc::c_int + && !parent_rfc724_mid.is_null() + && 0 != *parent_rfc724_mid.offset(0isize) as libc::c_int + { + new_references = dc_mprintf( + b"%s %s\x00" as *const u8 as *const libc::c_char, + parent_references, + parent_rfc724_mid, + ) + } else if !parent_references.is_null() + && 0 != *parent_references.offset(0isize) as libc::c_int + { + new_references = dc_strdup(parent_references) + } else if !parent_in_reply_to.is_null() + && 0 != *parent_in_reply_to.offset(0isize) as libc::c_int + && !parent_rfc724_mid.is_null() + && 0 != *parent_rfc724_mid.offset(0isize) as libc::c_int + { + new_references = dc_mprintf( + b"%s %s\x00" as *const u8 as *const libc::c_char, + parent_in_reply_to, + parent_rfc724_mid, + ) + } else if !parent_in_reply_to.is_null() + && 0 != *parent_in_reply_to.offset(0isize) as libc::c_int + { + new_references = dc_strdup(parent_in_reply_to) + } + free(parent_rfc724_mid as *mut libc::c_void); + free(parent_in_reply_to as *mut libc::c_void); + free(parent_references as *mut libc::c_void); } } @@ -547,9 +547,6 @@ impl<'a> Chat<'a> { } } - free(parent_rfc724_mid as *mut libc::c_void); - free(parent_in_reply_to as *mut libc::c_void); - free(parent_references as *mut libc::c_void); free(new_rfc724_mid as *mut libc::c_void); free(new_in_reply_to as *mut libc::c_void); free(new_references as *mut libc::c_void); From 1062ac6adeebb4700a94548e00056b2bea3399fa Mon Sep 17 00:00:00 2001 From: Dmitry Bogatov Date: Fri, 6 Sep 2019 23:14:14 +0000 Subject: [PATCH 12/19] Drop unsafe version of `get_parent_mime_headers` function --- src/chat.rs | 51 ++------------------------------------------------- 1 file changed, 2 insertions(+), 49 deletions(-) diff --git a/src/chat.rs b/src/chat.rs index 5f5e1ede0..c245c4295 100644 --- a/src/chat.rs +++ b/src/chat.rs @@ -171,54 +171,7 @@ impl<'a> Chat<'a> { return "Err".into(); } - unsafe fn get_parent_mime_headers( - &self, - parent_rfc724_mid: *mut *mut libc::c_char, - parent_in_reply_to: *mut *mut libc::c_char, - parent_references: *mut *mut libc::c_char, - ) -> Result<(), Error> { - if !(parent_rfc724_mid.is_null() - || parent_in_reply_to.is_null() - || parent_references.is_null()) - { - // prefer a last message that isn't from us - let next = self - .context - .sql - .query_row( - "SELECT rfc724_mid, mime_in_reply_to, mime_references \ - FROM msgs WHERE chat_id=?1 AND timestamp=(SELECT max(timestamp) \ - FROM msgs WHERE chat_id=?1 AND from_id!=?2);", - params![self.id as i32, DC_CONTACT_ID_SELF as i32], - |row| { - *parent_rfc724_mid = row.get::<_, String>(0)?.strdup(); - *parent_in_reply_to = row.get::<_, String>(1)?.strdup(); - *parent_references = row.get::<_, String>(2)?.strdup(); - Ok(()) - }, - ) - .is_ok(); - - if !next { - self.context.sql.query_row( - "SELECT rfc724_mid, mime_in_reply_to, mime_references \ - FROM msgs WHERE chat_id=?1 AND timestamp=(SELECT min(timestamp) \ - FROM msgs WHERE chat_id=?1 AND from_id==?2);", - params![self.id as i32, DC_CONTACT_ID_SELF as i32], - |row| { - *parent_rfc724_mid = row.get::<_, String>(0)?.strdup(); - *parent_in_reply_to = row.get::<_, String>(1)?.strdup(); - *parent_references = row.get::<_, String>(2)?.strdup(); - Ok(()) - }, - )?; - } - } - - Ok(()) - } - - pub fn get_parent_mime_headers_safe(&self) -> Option<(String, String, String)> { + pub fn get_parent_mime_headers(&self) -> Option<(String, String, String)> { let collect = |row: &rusqlite::Row| Ok((row.get(0)?, row.get(1)?, row.get(2)?)); let params = params![self.id as i32, DC_CONTACT_ID_SELF as i32]; let sql = &self.context.sql; @@ -420,7 +373,7 @@ impl<'a> Chat<'a> { msg.param.remove(Param::ErroneousE2ee); if !self.is_self_talk() { if let Some((parent_rfc724_mid, parent_in_reply_to, parent_references)) = - self.get_parent_mime_headers_safe() + self.get_parent_mime_headers() { let parent_rfc724_mid = parent_rfc724_mid.strdup(); let parent_in_reply_to = parent_in_reply_to.strdup(); From 1f82ba74aa906c7b80395fad115b5d2a88421d56 Mon Sep 17 00:00:00 2001 From: Dmitry Bogatov Date: Fri, 6 Sep 2019 23:24:39 +0000 Subject: [PATCH 13/19] Remove redundant checks in prepare_msg_raw() --- src/chat.rs | 29 ++++++++--------------------- 1 file changed, 8 insertions(+), 21 deletions(-) diff --git a/src/chat.rs b/src/chat.rs index c245c4295..9f7802b15 100644 --- a/src/chat.rs +++ b/src/chat.rs @@ -379,21 +379,14 @@ impl<'a> Chat<'a> { let parent_in_reply_to = parent_in_reply_to.strdup(); let parent_references = parent_references.strdup(); - if !parent_rfc724_mid.is_null() - && 0 != *parent_rfc724_mid.offset(0isize) as libc::c_int - { + if 0 != *parent_rfc724_mid.offset(0isize) as libc::c_int { new_in_reply_to = dc_strdup(parent_rfc724_mid) } - if !parent_references.is_null() { - let space: *mut libc::c_char; - space = strchr(parent_references, ' ' as i32); - if !space.is_null() { - *space = 0 as libc::c_char - } + let space = strchr(parent_references, ' ' as i32); + if !space.is_null() { + *space = 0 as libc::c_char } - if !parent_references.is_null() - && 0 != *parent_references.offset(0isize) as libc::c_int - && !parent_rfc724_mid.is_null() + if 0 != *parent_references.offset(0isize) as libc::c_int && 0 != *parent_rfc724_mid.offset(0isize) as libc::c_int { new_references = dc_mprintf( @@ -401,13 +394,9 @@ impl<'a> Chat<'a> { parent_references, parent_rfc724_mid, ) - } else if !parent_references.is_null() - && 0 != *parent_references.offset(0isize) as libc::c_int - { + } else if 0 != *parent_references.offset(0isize) as libc::c_int { new_references = dc_strdup(parent_references) - } else if !parent_in_reply_to.is_null() - && 0 != *parent_in_reply_to.offset(0isize) as libc::c_int - && !parent_rfc724_mid.is_null() + } else if 0 != *parent_in_reply_to.offset(0isize) as libc::c_int && 0 != *parent_rfc724_mid.offset(0isize) as libc::c_int { new_references = dc_mprintf( @@ -415,9 +404,7 @@ impl<'a> Chat<'a> { parent_in_reply_to, parent_rfc724_mid, ) - } else if !parent_in_reply_to.is_null() - && 0 != *parent_in_reply_to.offset(0isize) as libc::c_int - { + } else if 0 != *parent_in_reply_to.offset(0isize) as libc::c_int { new_references = dc_strdup(parent_in_reply_to) } free(parent_rfc724_mid as *mut libc::c_void); From 9bf7b0bf96f3295a3045271f48ee27ce7a7799ac Mon Sep 17 00:00:00 2001 From: Dmitry Bogatov Date: Sat, 7 Sep 2019 01:25:29 +0000 Subject: [PATCH 14/19] Use more of Rust, less of C strings in prepare_msg_raw() --- src/chat.rs | 61 ++++++++++++++++++++--------------------------------- 1 file changed, 23 insertions(+), 38 deletions(-) diff --git a/src/chat.rs b/src/chat.rs index 9f7802b15..7c7e5c4b1 100644 --- a/src/chat.rs +++ b/src/chat.rs @@ -248,8 +248,8 @@ impl<'a> Chat<'a> { let e2ee_enabled: libc::c_int; let mut OK_TO_CONTINUE = true; let mut new_rfc724_mid = ptr::null_mut(); - let mut new_references = ptr::null_mut(); - let mut new_in_reply_to = ptr::null_mut(); + let mut new_references = "".into(); + let mut new_in_reply_to = "".into(); let mut msg_id = 0; let mut to_id = 0; let mut location_id = 0; @@ -375,41 +375,28 @@ impl<'a> Chat<'a> { if let Some((parent_rfc724_mid, parent_in_reply_to, parent_references)) = self.get_parent_mime_headers() { - let parent_rfc724_mid = parent_rfc724_mid.strdup(); - let parent_in_reply_to = parent_in_reply_to.strdup(); - let parent_references = parent_references.strdup(); + if !parent_rfc724_mid.is_empty() { + new_in_reply_to = parent_rfc724_mid.clone(); + } + let parent_references = if let Some(n) = parent_references.find(' ') { + &parent_references[0..n] + } else { + &parent_references + }; - if 0 != *parent_rfc724_mid.offset(0isize) as libc::c_int { - new_in_reply_to = dc_strdup(parent_rfc724_mid) - } - let space = strchr(parent_references, ' ' as i32); - if !space.is_null() { - *space = 0 as libc::c_char - } - if 0 != *parent_references.offset(0isize) as libc::c_int - && 0 != *parent_rfc724_mid.offset(0isize) as libc::c_int + if !parent_references.is_empty() && !parent_rfc724_mid.is_empty() { + new_references = + format!("{} {}", parent_references, parent_rfc724_mid); + } else if !parent_references.is_empty() { + new_references = parent_references.to_string(); + } else if !parent_in_reply_to.is_empty() + && !parent_rfc724_mid.is_empty() { - new_references = dc_mprintf( - b"%s %s\x00" as *const u8 as *const libc::c_char, - parent_references, - parent_rfc724_mid, - ) - } else if 0 != *parent_references.offset(0isize) as libc::c_int { - new_references = dc_strdup(parent_references) - } else if 0 != *parent_in_reply_to.offset(0isize) as libc::c_int - && 0 != *parent_rfc724_mid.offset(0isize) as libc::c_int - { - new_references = dc_mprintf( - b"%s %s\x00" as *const u8 as *const libc::c_char, - parent_in_reply_to, - parent_rfc724_mid, - ) - } else if 0 != *parent_in_reply_to.offset(0isize) as libc::c_int { - new_references = dc_strdup(parent_in_reply_to) + new_references = + format!("{} {}", parent_in_reply_to, parent_rfc724_mid); + } else if !parent_in_reply_to.is_empty() { + new_references = parent_in_reply_to.clone(); } - free(parent_rfc724_mid as *mut libc::c_void); - free(parent_in_reply_to as *mut libc::c_void); - free(parent_references as *mut libc::c_void); } } @@ -461,8 +448,8 @@ impl<'a> Chat<'a> { msg.text, msg.param.to_string(), msg.hidden, - to_string(new_in_reply_to), - to_string(new_references), + new_in_reply_to, + new_references, location_id as i32, ] ).is_ok() { @@ -488,8 +475,6 @@ impl<'a> Chat<'a> { } free(new_rfc724_mid as *mut libc::c_void); - free(new_in_reply_to as *mut libc::c_void); - free(new_references as *mut libc::c_void); Ok(msg_id) } From a2281489a619b28ea5486587e3a4039269501ed9 Mon Sep 17 00:00:00 2001 From: Dmitry Bogatov Date: Sat, 7 Sep 2019 02:35:13 +0000 Subject: [PATCH 15/19] Create safe version of msgid-generating function --- src/dc_tools.rs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/dc_tools.rs b/src/dc_tools.rs index 6fa6135e0..9ecdb99a1 100644 --- a/src/dc_tools.rs +++ b/src/dc_tools.rs @@ -619,6 +619,21 @@ pub unsafe fn dc_create_outgoing_rfc724_mid( ret } +/// Generate globally-unique message-id for a new outgoing message. +/// +/// Note: Do not add a counter or any private data as as this may give +/// unneeded information to the receiver +pub fn dc_create_outgoing_rfc724_mid_safe(grpid: Option<&str>, from_addr: &str) -> String { + let hostname = from_addr + .find('@') + .map(|k| &from_addr[k..]) + .unwrap_or("@nohost"); + match grpid { + Some(grpid) => format!("Gr.{}.{}{}", grpid, dc_create_id(), hostname), + None => format!("Mr.{}.{}{}", dc_create_id(), dc_create_id(), hostname), + } +} + /// Extract the group id (grpid) from a message id (mid) /// /// # Arguments From 42bce7c0bf81616347462e30fc63a01fa5edda7f Mon Sep 17 00:00:00 2001 From: Dmitry Bogatov Date: Sat, 7 Sep 2019 02:54:28 +0000 Subject: [PATCH 16/19] Remove last C string from prepare_msg_raw() --- src/chat.rs | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/src/chat.rs b/src/chat.rs index 7c7e5c4b1..b716ab174 100644 --- a/src/chat.rs +++ b/src/chat.rs @@ -247,7 +247,6 @@ impl<'a> Chat<'a> { let mut do_guarantee_e2ee: libc::c_int; let e2ee_enabled: libc::c_int; let mut OK_TO_CONTINUE = true; - let mut new_rfc724_mid = ptr::null_mut(); let mut new_references = "".into(); let mut new_in_reply_to = "".into(); let mut msg_id = 0; @@ -270,15 +269,13 @@ impl<'a> Chat<'a> { ); } else { if let Some(from) = context.sql.get_config(context, "configured_addr") { - let from_c = CString::yolo(from); - new_rfc724_mid = dc_create_outgoing_rfc724_mid( - if self.typ == Chattype::Group || self.typ == Chattype::VerifiedGroup { - self.grpid.strdup() - } else { - ptr::null_mut() - }, - from_c.as_ptr(), - ); + let new_rfc724_mid = { + let grpid = match self.typ { + Chattype::Group | Chattype::VerifiedGroup => Some(self.grpid.as_str()), + _ => None, + }; + dc_create_outgoing_rfc724_mid_safe(grpid, &from) + }; if self.typ == Chattype::Single { if let Some(id) = context.sql.query_row_col( @@ -438,7 +435,7 @@ impl<'a> Chat<'a> { &context.sql, "INSERT INTO msgs (rfc724_mid, chat_id, from_id, to_id, timestamp, type, state, txt, param, hidden, mime_in_reply_to, mime_references, location_id) VALUES (?,?,?,?,?, ?,?,?,?,?, ?,?,?);", params![ - as_str(new_rfc724_mid), + new_rfc724_mid, self.id as i32, 1i32, to_id as i32, @@ -458,7 +455,7 @@ impl<'a> Chat<'a> { &context.sql, "msgs", "rfc724_mid", - as_str(new_rfc724_mid), + new_rfc724_mid, ); } else { error!( @@ -474,8 +471,6 @@ impl<'a> Chat<'a> { } } - free(new_rfc724_mid as *mut libc::c_void); - Ok(msg_id) } } From 400740fdbaa826f84880621fe6e692fcd30c5dd0 Mon Sep 17 00:00:00 2001 From: Dmitry Bogatov Date: Sat, 7 Sep 2019 03:03:35 +0000 Subject: [PATCH 17/19] Simplify prepare_msg_raw() using early return This commit will fail CI due incorrect formatting. It is done deliberately to simplify review process. --- src/chat.rs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/chat.rs b/src/chat.rs index b716ab174..874af1b20 100644 --- a/src/chat.rs +++ b/src/chat.rs @@ -258,7 +258,10 @@ impl<'a> Chat<'a> { || self.typ == Chattype::VerifiedGroup) { error!(context, 0, "Cannot send to chat type #{}.", self.typ,); - } else if (self.typ == Chattype::Group || self.typ == Chattype::VerifiedGroup) + return Ok(0); + } + + if (self.typ == Chattype::Group || self.typ == Chattype::VerifiedGroup) && 0 == is_contact_in_chat(context, self.id, 1 as u32) { log_event!( @@ -267,7 +270,9 @@ impl<'a> Chat<'a> { 0, "Cannot send message; self not in group.", ); - } else { + return Ok(0); + } + { if let Some(from) = context.sql.get_config(context, "configured_addr") { let new_rfc724_mid = { let grpid = match self.typ { From c4c08f2552cb51641ae628a8282bfc91aa3a23f7 Mon Sep 17 00:00:00 2001 From: Dmitry Bogatov Date: Sat, 7 Sep 2019 03:06:13 +0000 Subject: [PATCH 18/19] Remove ok_to_continue pattern from msg_prepare_raw() This commit will fail CI due incorrect formatting. It is done deliberately to simplify review process. --- src/chat.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/chat.rs b/src/chat.rs index 874af1b20..5cf47e80d 100644 --- a/src/chat.rs +++ b/src/chat.rs @@ -246,7 +246,6 @@ impl<'a> Chat<'a> { ) -> Result { let mut do_guarantee_e2ee: libc::c_int; let e2ee_enabled: libc::c_int; - let mut OK_TO_CONTINUE = true; let mut new_references = "".into(); let mut new_in_reply_to = "".into(); let mut msg_id = 0; @@ -295,7 +294,7 @@ impl<'a> Chat<'a> { context, 0, "Cannot send message, contact for chat #{} not found.", self.id, ); - OK_TO_CONTINUE = false; + return Ok(0); } } else { if self.typ == Chattype::Group || self.typ == Chattype::VerifiedGroup { @@ -305,7 +304,7 @@ impl<'a> Chat<'a> { } } } - if OK_TO_CONTINUE { + { /* check if we can guarantee E2EE for this message. if we guarantee E2EE, and circumstances change so that E2EE is no longer available at a later point (reset, changed settings), From 7d9fc682a0dfe846c8188d943feffdba2d8a13f1 Mon Sep 17 00:00:00 2001 From: Dmitry Bogatov Date: Sat, 7 Sep 2019 03:09:01 +0000 Subject: [PATCH 19/19] cargo-fmt --- src/chat.rs | 308 ++++++++++++++++++++++++++-------------------------- 1 file changed, 151 insertions(+), 157 deletions(-) diff --git a/src/chat.rs b/src/chat.rs index 5cf47e80d..87e624e60 100644 --- a/src/chat.rs +++ b/src/chat.rs @@ -271,170 +271,166 @@ impl<'a> Chat<'a> { ); return Ok(0); } - { - if let Some(from) = context.sql.get_config(context, "configured_addr") { - let new_rfc724_mid = { - let grpid = match self.typ { - Chattype::Group | Chattype::VerifiedGroup => Some(self.grpid.as_str()), - _ => None, - }; - dc_create_outgoing_rfc724_mid_safe(grpid, &from) - }; - if self.typ == Chattype::Single { - if let Some(id) = context.sql.query_row_col( - context, - "SELECT contact_id FROM chats_contacts WHERE chat_id=?;", - params![self.id as i32], - 0, - ) { - to_id = id; - } else { - error!( - context, - 0, "Cannot send message, contact for chat #{} not found.", self.id, - ); - return Ok(0); - } + if let Some(from) = context.sql.get_config(context, "configured_addr") { + let new_rfc724_mid = { + let grpid = match self.typ { + Chattype::Group | Chattype::VerifiedGroup => Some(self.grpid.as_str()), + _ => None, + }; + dc_create_outgoing_rfc724_mid_safe(grpid, &from) + }; + + if self.typ == Chattype::Single { + if let Some(id) = context.sql.query_row_col( + context, + "SELECT contact_id FROM chats_contacts WHERE chat_id=?;", + params![self.id as i32], + 0, + ) { + to_id = id; } else { - if self.typ == Chattype::Group || self.typ == Chattype::VerifiedGroup { - if self.param.get_int(Param::Unpromoted).unwrap_or_default() == 1 { - self.param.remove(Param::Unpromoted); - self.update_param().unwrap(); - } + error!( + context, + 0, "Cannot send message, contact for chat #{} not found.", self.id, + ); + return Ok(0); + } + } else { + if self.typ == Chattype::Group || self.typ == Chattype::VerifiedGroup { + if self.param.get_int(Param::Unpromoted).unwrap_or_default() == 1 { + self.param.remove(Param::Unpromoted); + self.update_param().unwrap(); } } + } + + /* check if we can guarantee E2EE for this message. + if we guarantee E2EE, and circumstances change + so that E2EE is no longer available at a later point (reset, changed settings), + we do not send the message out at all */ + do_guarantee_e2ee = 0; + e2ee_enabled = context + .sql + .get_config_int(context, "e2ee_enabled") + .unwrap_or_else(|| 1); + if 0 != e2ee_enabled + && msg.param.get_int(Param::ForcePlaintext).unwrap_or_default() == 0 + { + let mut can_encrypt = 1; + let mut all_mutual = 1; + + let res = context.sql.query_row( + "SELECT ps.prefer_encrypted, c.addr \ + FROM chats_contacts cc \ + LEFT JOIN contacts c ON cc.contact_id=c.id \ + LEFT JOIN acpeerstates ps ON c.addr=ps.addr \ + WHERE cc.chat_id=? AND cc.contact_id>9;", + params![self.id], + |row| { + let state: String = row.get(1)?; + + if let Some(prefer_encrypted) = row.get::<_, Option>(0)? { + if prefer_encrypted != 1 { + info!( + context, + 0, + "[autocrypt] peerstate for {} is {}", + state, + if prefer_encrypted == 0 { + "NOPREFERENCE" + } else { + "RESET" + }, + ); + all_mutual = 0; + } + } else { + info!(context, 0, "[autocrypt] no peerstate for {}", state,); + can_encrypt = 0; + all_mutual = 0; + } + Ok(()) + }, + ); + match res { + Ok(_) => {} + Err(err) => { + warn!(context, 0, "chat: failed to load peerstates: {:?}", err); + } + } + + if 0 != can_encrypt { + if 0 != all_mutual { + do_guarantee_e2ee = 1; + } else if last_msg_in_chat_encrypted(context, &context.sql, self.id) { + do_guarantee_e2ee = 1; + } + } + } + if 0 != do_guarantee_e2ee { + msg.param.set_int(Param::GuranteeE2ee, 1); + } + msg.param.remove(Param::ErroneousE2ee); + if !self.is_self_talk() { + if let Some((parent_rfc724_mid, parent_in_reply_to, parent_references)) = + self.get_parent_mime_headers() { - /* check if we can guarantee E2EE for this message. - if we guarantee E2EE, and circumstances change - so that E2EE is no longer available at a later point (reset, changed settings), - we do not send the message out at all */ - do_guarantee_e2ee = 0; - e2ee_enabled = context - .sql - .get_config_int(context, "e2ee_enabled") - .unwrap_or_else(|| 1); - if 0 != e2ee_enabled - && msg.param.get_int(Param::ForcePlaintext).unwrap_or_default() == 0 - { - let mut can_encrypt = 1; - let mut all_mutual = 1; - - let res = context.sql.query_row( - "SELECT ps.prefer_encrypted, c.addr \ - FROM chats_contacts cc \ - LEFT JOIN contacts c ON cc.contact_id=c.id \ - LEFT JOIN acpeerstates ps ON c.addr=ps.addr \ - WHERE cc.chat_id=? AND cc.contact_id>9;", - params![self.id], - |row| { - let state: String = row.get(1)?; - - if let Some(prefer_encrypted) = row.get::<_, Option>(0)? { - if prefer_encrypted != 1 { - info!( - context, - 0, - "[autocrypt] peerstate for {} is {}", - state, - if prefer_encrypted == 0 { - "NOPREFERENCE" - } else { - "RESET" - }, - ); - all_mutual = 0; - } - } else { - info!(context, 0, "[autocrypt] no peerstate for {}", state,); - can_encrypt = 0; - all_mutual = 0; - } - Ok(()) - }, - ); - match res { - Ok(_) => {} - Err(err) => { - warn!(context, 0, "chat: failed to load peerstates: {:?}", err); - } - } - - if 0 != can_encrypt { - if 0 != all_mutual { - do_guarantee_e2ee = 1; - } else if last_msg_in_chat_encrypted(context, &context.sql, self.id) { - do_guarantee_e2ee = 1; - } - } + if !parent_rfc724_mid.is_empty() { + new_in_reply_to = parent_rfc724_mid.clone(); } - if 0 != do_guarantee_e2ee { - msg.param.set_int(Param::GuranteeE2ee, 1); + let parent_references = if let Some(n) = parent_references.find(' ') { + &parent_references[0..n] + } else { + &parent_references + }; + + if !parent_references.is_empty() && !parent_rfc724_mid.is_empty() { + new_references = format!("{} {}", parent_references, parent_rfc724_mid); + } else if !parent_references.is_empty() { + new_references = parent_references.to_string(); + } else if !parent_in_reply_to.is_empty() && !parent_rfc724_mid.is_empty() { + new_references = format!("{} {}", parent_in_reply_to, parent_rfc724_mid); + } else if !parent_in_reply_to.is_empty() { + new_references = parent_in_reply_to.clone(); } - msg.param.remove(Param::ErroneousE2ee); - if !self.is_self_talk() { - if let Some((parent_rfc724_mid, parent_in_reply_to, parent_references)) = - self.get_parent_mime_headers() - { - if !parent_rfc724_mid.is_empty() { - new_in_reply_to = parent_rfc724_mid.clone(); - } - let parent_references = if let Some(n) = parent_references.find(' ') { - &parent_references[0..n] - } else { - &parent_references - }; + } + } - if !parent_references.is_empty() && !parent_rfc724_mid.is_empty() { - new_references = - format!("{} {}", parent_references, parent_rfc724_mid); - } else if !parent_references.is_empty() { - new_references = parent_references.to_string(); - } else if !parent_in_reply_to.is_empty() - && !parent_rfc724_mid.is_empty() - { - new_references = - format!("{} {}", parent_in_reply_to, parent_rfc724_mid); - } else if !parent_in_reply_to.is_empty() { - new_references = parent_in_reply_to.clone(); - } - } - } + // add independent location to database - // add independent location to database + if msg.param.exists(Param::SetLatitude) { + if sql::execute( + context, + &context.sql, + "INSERT INTO locations \ + (timestamp,from_id,chat_id, latitude,longitude,independent)\ + VALUES (?,?,?, ?,?,1);", + params![ + timestamp, + DC_CONTACT_ID_SELF, + self.id as i32, + msg.param.get_float(Param::SetLatitude).unwrap_or_default(), + msg.param.get_float(Param::SetLongitude).unwrap_or_default(), + ], + ) + .is_ok() + { + location_id = sql::get_rowid2( + context, + &context.sql, + "locations", + "timestamp", + timestamp, + "from_id", + DC_CONTACT_ID_SELF as i32, + ); + } + } - if msg.param.exists(Param::SetLatitude) { - if sql::execute( - context, - &context.sql, - "INSERT INTO locations \ - (timestamp,from_id,chat_id, latitude,longitude,independent)\ - VALUES (?,?,?, ?,?,1);", - params![ - timestamp, - DC_CONTACT_ID_SELF, - self.id as i32, - msg.param.get_float(Param::SetLatitude).unwrap_or_default(), - msg.param.get_float(Param::SetLongitude).unwrap_or_default(), - ], - ) - .is_ok() - { - location_id = sql::get_rowid2( - context, - &context.sql, - "locations", - "timestamp", - timestamp, - "from_id", - DC_CONTACT_ID_SELF as i32, - ); - } - } + // add message to the database - // add message to the database - - if sql::execute( + if sql::execute( context, &context.sql, "INSERT INTO msgs (rfc724_mid, chat_id, from_id, to_id, timestamp, type, state, txt, param, hidden, mime_in_reply_to, mime_references, location_id) VALUES (?,?,?,?,?, ?,?,?,?,?, ?,?,?);", @@ -469,10 +465,8 @@ impl<'a> Chat<'a> { self.id, ); } - } - } else { - error!(context, 0, "Cannot send message, not configured.",); - } + } else { + error!(context, 0, "Cannot send message, not configured.",); } Ok(msg_id)