Rustify type of dc_mimeparser_t.subject

This commit is contained in:
Dmitry Bogatov
2019-09-06 06:14:27 +00:00
parent 743e4deb36
commit a4e4b0fc17
2 changed files with 43 additions and 37 deletions

View File

@@ -50,7 +50,7 @@ pub struct dc_mimeparser_t<'a> {
pub header: HashMap<String, *mut mailimf_field>,
pub header_root: *mut mailimf_fields,
pub header_protected: *mut mailimf_fields,
pub subject: *mut libc::c_char,
pub subject: Option<String>,
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");

View File

@@ -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)