mirror of
https://github.com/chatmail/core.git
synced 2026-04-21 07:26:29 +03:00
Store dc_mimeparser_t::parts as Vec instead of carray
This commit is contained in:
@@ -44,7 +44,7 @@ pub struct dc_mimepart_t {
|
||||
#[derive(Clone)]
|
||||
#[allow(non_camel_case_types)]
|
||||
pub struct dc_mimeparser_t<'a> {
|
||||
pub parts: *mut carray,
|
||||
pub parts: Vec<dc_mimepart_t>,
|
||||
pub mimeroot: *mut mailmime,
|
||||
pub header: HashMap<String, *mut mailimf_field>,
|
||||
pub header_root: *mut mailimf_fields,
|
||||
@@ -71,7 +71,7 @@ static mut S_GENERATE_COMPOUND_MSGS: libc::c_int = 1i32;
|
||||
|
||||
pub unsafe fn dc_mimeparser_new(context: &Context) -> dc_mimeparser_t {
|
||||
dc_mimeparser_t {
|
||||
parts: carray_new(16i32 as libc::c_uint),
|
||||
parts: Vec::new(),
|
||||
mimeroot: std::ptr::null_mut(),
|
||||
header: Default::default(),
|
||||
header_root: std::ptr::null_mut(),
|
||||
@@ -91,25 +91,13 @@ pub unsafe fn dc_mimeparser_new(context: &Context) -> dc_mimeparser_t {
|
||||
|
||||
pub unsafe fn dc_mimeparser_unref(mimeparser: &mut dc_mimeparser_t) {
|
||||
dc_mimeparser_empty(mimeparser);
|
||||
if !(*mimeparser).parts.is_null() {
|
||||
carray_free((*mimeparser).parts);
|
||||
}
|
||||
}
|
||||
|
||||
pub unsafe fn dc_mimeparser_empty(mimeparser: &mut dc_mimeparser_t) {
|
||||
if !(*mimeparser).parts.is_null() {
|
||||
let mut i: libc::c_int;
|
||||
let cnt: libc::c_int = carray_count((*mimeparser).parts) as libc::c_int;
|
||||
i = 0i32;
|
||||
while i < cnt {
|
||||
let part = carray_get((*mimeparser).parts, i as libc::c_uint) as *mut dc_mimepart_t;
|
||||
if !part.is_null() {
|
||||
dc_mimepart_unref(*Box::from_raw(part));
|
||||
}
|
||||
i += 1
|
||||
}
|
||||
carray_set_size((*mimeparser).parts, 0i32 as libc::c_uint);
|
||||
for part in mimeparser.parts.drain(..) {
|
||||
dc_mimepart_unref(part);
|
||||
}
|
||||
assert!(mimeparser.parts.is_empty());
|
||||
(*mimeparser).header_root = 0 as *mut mailimf_fields;
|
||||
(*mimeparser).header.clear();
|
||||
if !(*mimeparser).header_protected.is_null() {
|
||||
@@ -183,29 +171,34 @@ pub unsafe fn dc_mimeparser_parse(
|
||||
(*mimeparser).is_send_by_messenger = 1i32
|
||||
}
|
||||
if !dc_mimeparser_lookup_field(mimeparser, "Autocrypt-Setup-Message").is_null() {
|
||||
let mut i: libc::c_int;
|
||||
let mut has_setup_file: libc::c_int = 0i32;
|
||||
i = 0i32;
|
||||
while (i as libc::c_uint) < carray_count((*mimeparser).parts) {
|
||||
let part: *mut dc_mimepart_t =
|
||||
carray_get((*mimeparser).parts, i as libc::c_uint) as *mut dc_mimepart_t;
|
||||
if (*part).int_mimetype == 111i32 {
|
||||
for part in &mimeparser.parts {
|
||||
if part.int_mimetype == 111i32 {
|
||||
has_setup_file = 1i32
|
||||
}
|
||||
i += 1
|
||||
}
|
||||
if 0 != has_setup_file {
|
||||
(*mimeparser).is_system_message = 6i32;
|
||||
i = 0i32;
|
||||
while (i as libc::c_uint) < carray_count((*mimeparser).parts) {
|
||||
let part_0 =
|
||||
carray_get((*mimeparser).parts, i as libc::c_uint) as *mut dc_mimepart_t;
|
||||
if (*part_0).int_mimetype != 111i32 {
|
||||
dc_mimepart_unref(*Box::from_raw(part_0));
|
||||
carray_delete_slow((*mimeparser).parts, i as libc::c_uint);
|
||||
i -= 1
|
||||
mimeparser.is_system_message = 6i32;
|
||||
|
||||
// TODO: replace the following code with this
|
||||
// once drain_filter stabilizes.
|
||||
//
|
||||
// See https://doc.rust-lang.org/std/vec/struct.Vec.html#method.drain_filter
|
||||
// and https://github.com/rust-lang/rust/issues/43244
|
||||
//
|
||||
// mimeparser
|
||||
// .parts
|
||||
// .drain_filter(|part| part.int_mimetype != 111)
|
||||
// .for_each(|part| dc_mimepart_unref(part));
|
||||
|
||||
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);
|
||||
} else {
|
||||
i += 1;
|
||||
}
|
||||
i += 1
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -224,40 +217,42 @@ pub unsafe fn dc_mimeparser_parse(
|
||||
}
|
||||
}
|
||||
if !dc_mimeparser_lookup_field(mimeparser, "Chat-Group-Image").is_null()
|
||||
&& carray_count((*mimeparser).parts) >= 1i32 as libc::c_uint
|
||||
&& !mimeparser.parts.is_empty()
|
||||
{
|
||||
let textpart: *mut dc_mimepart_t =
|
||||
carray_get((*mimeparser).parts, 0i32 as libc::c_uint) as *mut dc_mimepart_t;
|
||||
if (*textpart).type_0 == 10i32 {
|
||||
if carray_count((*mimeparser).parts) >= 2i32 as libc::c_uint {
|
||||
let mut imgpart: *mut dc_mimepart_t =
|
||||
carray_get((*mimeparser).parts, 1i32 as libc::c_uint) as *mut dc_mimepart_t;
|
||||
if (*imgpart).type_0 == 20i32 {
|
||||
(*imgpart).is_meta = 1i32
|
||||
let textpart = &mimeparser.parts[0];
|
||||
if textpart.type_0 == 10i32 {
|
||||
if mimeparser.parts.len() >= 2 {
|
||||
let imgpart = &mut mimeparser.parts[1];
|
||||
if imgpart.type_0 == 20i32 {
|
||||
imgpart.is_meta = 1i32
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if 0 != (*mimeparser).is_send_by_messenger
|
||||
&& 0 != S_GENERATE_COMPOUND_MSGS
|
||||
&& carray_count((*mimeparser).parts) == 2i32 as libc::c_uint
|
||||
&& mimeparser.parts.len() == 2
|
||||
{
|
||||
let mut textpart_0 = carray_get((*mimeparser).parts, 0) as *mut dc_mimepart_t;
|
||||
let mut filepart = carray_get((*mimeparser).parts, 1) as *mut dc_mimepart_t;
|
||||
if (*textpart_0).type_0 == 10i32
|
||||
&& ((*filepart).type_0 == 20i32
|
||||
|| (*filepart).type_0 == 21i32
|
||||
|| (*filepart).type_0 == 40i32
|
||||
|| (*filepart).type_0 == 41i32
|
||||
|| (*filepart).type_0 == 50i32
|
||||
|| (*filepart).type_0 == 60i32)
|
||||
&& 0 == (*filepart).is_meta
|
||||
let need_drop: bool;
|
||||
{
|
||||
free((*filepart).msg as *mut libc::c_void);
|
||||
(*filepart).msg = (*textpart_0).msg;
|
||||
(*textpart_0).msg = 0 as *mut libc::c_char;
|
||||
dc_mimepart_unref(*Box::from_raw(textpart_0));
|
||||
carray_delete_slow((*mimeparser).parts, 0i32 as libc::c_uint);
|
||||
let textpart = &mimeparser.parts[0];
|
||||
let filepart = &mimeparser.parts[1];
|
||||
need_drop = textpart.type_0 == 10i32
|
||||
&& (filepart.type_0 == 20i32
|
||||
|| filepart.type_0 == 21i32
|
||||
|| filepart.type_0 == 40i32
|
||||
|| filepart.type_0 == 41i32
|
||||
|| filepart.type_0 == 50i32
|
||||
|| filepart.type_0 == 60i32)
|
||||
&& 0 == filepart.is_meta;
|
||||
}
|
||||
|
||||
if need_drop {
|
||||
free(mimeparser.parts[1].msg as *mut libc::c_void);
|
||||
let mut textpart = mimeparser.parts.swap_remove(0);
|
||||
mimeparser.parts[1].msg = textpart.msg;
|
||||
textpart.msg = 0 as *mut libc::c_char;
|
||||
dc_mimepart_unref(textpart);
|
||||
}
|
||||
}
|
||||
if !(*mimeparser).subject.is_null() {
|
||||
@@ -284,24 +279,16 @@ pub unsafe fn dc_mimeparser_parse(
|
||||
}
|
||||
dc_trim(subj);
|
||||
if 0 != *subj.offset(0isize) {
|
||||
let mut i_0: libc::c_int;
|
||||
let icnt: libc::c_int = carray_count((*mimeparser).parts) as libc::c_int;
|
||||
i_0 = 0i32;
|
||||
while i_0 < icnt {
|
||||
let mut part_1: *mut dc_mimepart_t =
|
||||
carray_get((*mimeparser).parts, i_0 as libc::c_uint)
|
||||
as *mut dc_mimepart_t;
|
||||
if (*part_1).type_0 == 10i32 {
|
||||
for part in mimeparser.parts.iter_mut() {
|
||||
if part.type_0 == 10i32 {
|
||||
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,
|
||||
(*part_1).msg,
|
||||
part.msg,
|
||||
);
|
||||
free((*part_1).msg as *mut libc::c_void);
|
||||
(*part_1).msg = new_txt;
|
||||
free(part.msg as *mut libc::c_void);
|
||||
part.msg = new_txt;
|
||||
break;
|
||||
} else {
|
||||
i_0 += 1
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -309,30 +296,24 @@ pub unsafe fn dc_mimeparser_parse(
|
||||
}
|
||||
}
|
||||
if 0 != (*mimeparser).is_forwarded {
|
||||
let mut i_1: libc::c_int;
|
||||
let icnt_0: libc::c_int = carray_count((*mimeparser).parts) as libc::c_int;
|
||||
i_1 = 0i32;
|
||||
while i_1 < icnt_0 {
|
||||
let part_2 =
|
||||
carray_get((*mimeparser).parts, i_1 as libc::c_uint) as *mut dc_mimepart_t;
|
||||
(*part_2).param.set_int(Param::Forwarded, 1);
|
||||
i_1 += 1
|
||||
for part in mimeparser.parts.iter_mut() {
|
||||
part.param.set_int(Param::Forwarded, 1);
|
||||
}
|
||||
}
|
||||
if carray_count((*mimeparser).parts) == 1i32 as libc::c_uint {
|
||||
let mut part_3: *mut dc_mimepart_t =
|
||||
carray_get((*mimeparser).parts, 0i32 as libc::c_uint) as *mut dc_mimepart_t;
|
||||
if (*part_3).type_0 == 40i32 {
|
||||
if mimeparser.parts.len() == 1 {
|
||||
if mimeparser.parts[0].type_0 == 40i32 {
|
||||
if !dc_mimeparser_lookup_optional_field(
|
||||
mimeparser,
|
||||
b"Chat-Voice-Message\x00" as *const u8 as *const libc::c_char,
|
||||
)
|
||||
.is_null()
|
||||
{
|
||||
(*part_3).type_0 = 41i32
|
||||
let part_mut = &mut mimeparser.parts[0];
|
||||
part_mut.type_0 = 41i32
|
||||
}
|
||||
}
|
||||
if (*part_3).type_0 == 40i32 || (*part_3).type_0 == 41i32 || (*part_3).type_0 == 50i32 {
|
||||
let part = &mimeparser.parts[0];
|
||||
if part.type_0 == 40i32 || part.type_0 == 41i32 || part.type_0 == 50i32 {
|
||||
let field_0 = dc_mimeparser_lookup_optional_field(
|
||||
mimeparser,
|
||||
b"Chat-Duration\x00" as *const u8 as *const libc::c_char,
|
||||
@@ -340,7 +321,8 @@ pub unsafe fn dc_mimeparser_parse(
|
||||
if !field_0.is_null() {
|
||||
let duration_ms: libc::c_int = dc_atoi_null_is_0((*field_0).fld_value);
|
||||
if duration_ms > 0i32 && duration_ms < 24i32 * 60i32 * 60i32 * 1000i32 {
|
||||
(*part_3).param.set_int(Param::Duration, duration_ms);
|
||||
let part_mut = &mut mimeparser.parts[0];
|
||||
part_mut.param.set_int(Param::Duration, duration_ms);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -350,7 +332,7 @@ pub unsafe fn dc_mimeparser_parse(
|
||||
mimeparser,
|
||||
b"Chat-Disposition-Notification-To\x00" as *const u8 as *const libc::c_char,
|
||||
);
|
||||
if !dn_field.is_null() && !dc_mimeparser_get_last_nonmeta(mimeparser).is_null() {
|
||||
if !dn_field.is_null() && dc_mimeparser_get_last_nonmeta(mimeparser).is_some() {
|
||||
let mut mb_list: *mut mailimf_mailbox_list = 0 as *mut mailimf_mailbox_list;
|
||||
let mut index_0: size_t = 0i32 as size_t;
|
||||
if mailimf_mailbox_list_parse(
|
||||
@@ -374,10 +356,9 @@ pub unsafe fn dc_mimeparser_parse(
|
||||
);
|
||||
if !from_addr.is_null() {
|
||||
if strcmp(from_addr, dn_to_addr) == 0i32 {
|
||||
let part_4: *mut dc_mimepart_t =
|
||||
dc_mimeparser_get_last_nonmeta(mimeparser);
|
||||
if !part_4.is_null() {
|
||||
(*part_4).param.set_int(Param::WantsMdn, 1);
|
||||
if let Some(part_4) = dc_mimeparser_get_last_nonmeta(mimeparser)
|
||||
{
|
||||
part_4.param.set_int(Param::WantsMdn, 1);
|
||||
}
|
||||
}
|
||||
free(from_addr as *mut libc::c_void);
|
||||
@@ -391,7 +372,7 @@ pub unsafe fn dc_mimeparser_parse(
|
||||
}
|
||||
}
|
||||
/* Cleanup - and try to create at least an empty part if there are no parts yet */
|
||||
if dc_mimeparser_get_last_nonmeta(mimeparser).is_null() && (*mimeparser).reports.is_empty() {
|
||||
if dc_mimeparser_get_last_nonmeta(mimeparser).is_none() && (*mimeparser).reports.is_empty() {
|
||||
let mut part_5 = dc_mimepart_new();
|
||||
part_5.type_0 = 10i32;
|
||||
if !(*mimeparser).subject.is_null() && 0 == (*mimeparser).is_send_by_messenger {
|
||||
@@ -399,11 +380,7 @@ pub unsafe fn dc_mimeparser_parse(
|
||||
} else {
|
||||
part_5.msg = dc_strdup(b"\x00" as *const u8 as *const libc::c_char)
|
||||
}
|
||||
carray_add(
|
||||
(*mimeparser).parts,
|
||||
Box::into_raw(Box::new(part_5)) as *mut libc::c_void,
|
||||
0 as *mut libc::c_uint,
|
||||
);
|
||||
mimeparser.parts.push(part_5);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -422,22 +399,14 @@ unsafe fn dc_mimepart_new() -> dc_mimepart_t {
|
||||
}
|
||||
}
|
||||
|
||||
pub unsafe fn dc_mimeparser_get_last_nonmeta(mimeparser: &dc_mimeparser_t) -> *mut dc_mimepart_t {
|
||||
if !(*mimeparser).parts.is_null() {
|
||||
let mut i: libc::c_int;
|
||||
let icnt: libc::c_int = carray_count((*mimeparser).parts) as libc::c_int;
|
||||
i = icnt - 1i32;
|
||||
while i >= 0i32 {
|
||||
let part: *mut dc_mimepart_t =
|
||||
carray_get(mimeparser.parts, i as libc::c_uint) as *mut dc_mimepart_t;
|
||||
if !part.is_null() && 0 == (*part).is_meta {
|
||||
return part;
|
||||
}
|
||||
i -= 1
|
||||
}
|
||||
}
|
||||
|
||||
0 as *mut 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)
|
||||
}
|
||||
|
||||
/*the result must be freed*/
|
||||
@@ -664,11 +633,7 @@ unsafe fn dc_mimeparser_parse_mime_recursive(
|
||||
msg_body.as_ptr(),
|
||||
);
|
||||
part.msg_raw = dc_strdup(part.msg);
|
||||
carray_add(
|
||||
(*mimeparser).parts,
|
||||
Box::into_raw(Box::new(part)) as *mut libc::c_void,
|
||||
0 as *mut libc::c_uint,
|
||||
);
|
||||
mimeparser.parts.push(part);
|
||||
any_part_added = 1i32;
|
||||
(*mimeparser).decrypting_failed = 1i32
|
||||
}
|
||||
@@ -1125,7 +1090,7 @@ unsafe fn dc_mimeparser_add_single_part_if_known(
|
||||
mime: *mut mailmime,
|
||||
) -> libc::c_int {
|
||||
let mut current_block: u64;
|
||||
let old_part_count: libc::c_int = carray_count(mimeparser.parts) as libc::c_int;
|
||||
let old_part_count = mimeparser.parts.len();
|
||||
let mime_type: libc::c_int;
|
||||
let mime_data: *mut mailmime_data;
|
||||
let file_suffix: *mut libc::c_char = 0 as *mut libc::c_char;
|
||||
@@ -1418,16 +1383,16 @@ unsafe fn dc_mimeparser_add_single_part_if_known(
|
||||
free(file_suffix as *mut libc::c_void);
|
||||
free(desired_filename as *mut libc::c_void);
|
||||
free(raw_mime as *mut libc::c_void);
|
||||
return if carray_count((*mimeparser).parts) > old_part_count as libc::c_uint {
|
||||
1i32
|
||||
return if mimeparser.parts.len() > old_part_count {
|
||||
1
|
||||
} else {
|
||||
0i32
|
||||
0
|
||||
};
|
||||
}
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
unsafe fn do_add_single_file_part(
|
||||
parser: &dc_mimeparser_t,
|
||||
parser: &mut dc_mimeparser_t,
|
||||
msg_type: libc::c_int,
|
||||
mime_type: libc::c_int,
|
||||
raw_mime: *const libc::c_char,
|
||||
@@ -1476,17 +1441,13 @@ unsafe fn do_add_single_file_part(
|
||||
free(pathNfilename as *mut libc::c_void);
|
||||
}
|
||||
|
||||
unsafe fn do_add_single_part(parser: &dc_mimeparser_t, mut part: dc_mimepart_t) {
|
||||
unsafe fn do_add_single_part(parser: &mut dc_mimeparser_t, mut part: dc_mimepart_t) {
|
||||
if 0 != (*parser).e2ee_helper.encrypted && (*parser).e2ee_helper.signatures.len() > 0 {
|
||||
part.param.set_int(Param::GuranteeE2ee, 1);
|
||||
} else if 0 != (*parser).e2ee_helper.encrypted {
|
||||
part.param.set_int(Param::ErroneousE2ee, 0x2);
|
||||
}
|
||||
carray_add(
|
||||
(*parser).parts,
|
||||
Box::into_raw(Box::new(part)) as *mut libc::c_void,
|
||||
0 as *mut libc::c_uint,
|
||||
);
|
||||
parser.parts.push(part);
|
||||
}
|
||||
|
||||
// TODO should return bool /rtn
|
||||
@@ -1773,27 +1734,20 @@ pub unsafe fn mailimf_find_field(
|
||||
}
|
||||
|
||||
pub unsafe fn dc_mimeparser_repl_msg_by_error(
|
||||
mimeparser: &dc_mimeparser_t,
|
||||
mimeparser: &mut dc_mimeparser_t,
|
||||
error_msg: *const libc::c_char,
|
||||
) {
|
||||
let mut part: *mut dc_mimepart_t;
|
||||
let mut i: libc::c_int;
|
||||
if (*mimeparser).parts.is_null() || carray_count((*mimeparser).parts) <= 0i32 as libc::c_uint {
|
||||
if mimeparser.parts.is_empty() {
|
||||
return;
|
||||
}
|
||||
part = carray_get((*mimeparser).parts, 0i32 as libc::c_uint) as *mut dc_mimepart_t;
|
||||
(*part).type_0 = 10i32;
|
||||
free((*part).msg as *mut libc::c_void);
|
||||
(*part).msg = dc_mprintf(b"[%s]\x00" as *const u8 as *const libc::c_char, error_msg);
|
||||
i = 1i32;
|
||||
while (i as libc::c_uint) < carray_count((*mimeparser).parts) {
|
||||
part = carray_get((*mimeparser).parts, i as libc::c_uint) as *mut dc_mimepart_t;
|
||||
if !part.is_null() {
|
||||
dc_mimepart_unref(*Box::from_raw(part));
|
||||
}
|
||||
i += 1
|
||||
let part = &mut mimeparser.parts[0];
|
||||
part.type_0 = 10i32;
|
||||
free(part.msg as *mut libc::c_void);
|
||||
part.msg = dc_mprintf(b"[%s]\x00" as *const u8 as *const libc::c_char, error_msg);
|
||||
for part in mimeparser.parts.drain(1..) {
|
||||
dc_mimepart_unref(part);
|
||||
}
|
||||
carray_set_size((*mimeparser).parts, 1i32 as libc::c_uint);
|
||||
assert_eq!(mimeparser.parts.len(), 1);
|
||||
}
|
||||
|
||||
/*the result is a pointer to mime, must not be freed*/
|
||||
|
||||
Reference in New Issue
Block a user