diff --git a/src/dc_mimeparser.rs b/src/dc_mimeparser.rs index 59c83df1f..b7a1ea1cb 100644 --- a/src/dc_mimeparser.rs +++ b/src/dc_mimeparser.rs @@ -1174,90 +1174,82 @@ unsafe fn dc_mimeparser_add_single_part_if_known( if simplifier.is_none() { simplifier = Some(dc_simplify_t::new()); } - /* get from `Content-Type: text/...; charset=utf-8`; must not be free()'d */ - let charset: *const libc::c_char = - mailmime_content_charset_get((*mime).mm_content_type); - if !charset.is_null() - && strcmp( - charset, - b"utf-8\x00" as *const u8 as *const libc::c_char, - ) != 0i32 - && strcmp( - charset, - b"UTF-8\x00" as *const u8 as *const libc::c_char, - ) != 0i32 - { - if let Some(encoding) = Charset::for_label( - CStr::from_ptr(charset).to_str().unwrap().as_bytes(), - ) { - let data = std::slice::from_raw_parts( - decoded_data as *const u8, - decoded_data_bytes, - ); + /* get from `Content-Type: text/...; charset=utf-8`; must not be free()'d */ + let charset: *const libc::c_char = + mailmime_content_charset_get((*mime).mm_content_type); + if !charset.is_null() + && strcmp(charset, b"utf-8\x00" as *const u8 as *const libc::c_char) + != 0i32 + && strcmp(charset, b"UTF-8\x00" as *const u8 as *const libc::c_char) + != 0i32 + { + if let Some(encoding) = Charset::for_label( + CStr::from_ptr(charset).to_str().unwrap().as_bytes(), + ) { + let data = std::slice::from_raw_parts( + decoded_data as *const u8, + decoded_data_bytes, + ); - let (res, _, _) = encoding.decode(data); - if res.is_empty() { - /* no error - but nothing to add */ - current_block = 8795901732489102124; - } else { - decoded_data_bytes = res.len(); - decoded_data = res.as_ptr() as *const libc::c_char; - current_block = 17788412896529399552; - } - } else { - warn!( - mimeparser.context, - 0, - "Cannot convert {} bytes from \"{}\" to \"utf-8\".", - decoded_data_bytes as libc::c_int, - as_str(charset), - ); - current_block = 17788412896529399552; - } + let (res, _, _) = encoding.decode(data); + if res.is_empty() { + /* no error - but nothing to add */ + current_block = 8795901732489102124; } else { + decoded_data_bytes = res.len(); + decoded_data = res.as_ptr() as *const libc::c_char; current_block = 17788412896529399552; } - match current_block { - 8795901732489102124 => {} - _ => { - /* check header directly as is_send_by_messenger is not yet set up */ - let is_msgrmsg: libc::c_int = - (dc_mimeparser_lookup_optional_field( - &mimeparser, - b"Chat-Version\x00" as *const u8 - as *const libc::c_char, - ) != 0 as *mut libc::c_void - as *mut mailimf_optional_field) - as libc::c_int; - let simplified_txt: *mut libc::c_char = - simplifier.unwrap().simplify( - decoded_data, - decoded_data_bytes as libc::c_int, - if mime_type == 70i32 { 1i32 } else { 0i32 }, - is_msgrmsg, - ); - if !simplified_txt.is_null() - && 0 != *simplified_txt.offset(0isize) as libc::c_int - { - part = dc_mimepart_new(); - (*part).type_0 = 10i32; - (*part).int_mimetype = mime_type; - (*part).msg = simplified_txt; - (*part).msg_raw = strndup( - decoded_data, - decoded_data_bytes as libc::c_ulong, - ); - do_add_single_part(mimeparser, part); - part = 0 as *mut dc_mimepart_t - } else { - free(simplified_txt as *mut libc::c_void); - } - if 0 != simplifier.unwrap().is_forwarded { - (*mimeparser).is_forwarded = 1i32 - } - current_block = 10261677128829721533; - } + } else { + warn!( + mimeparser.context, + 0, + "Cannot convert {} bytes from \"{}\" to \"utf-8\".", + decoded_data_bytes as libc::c_int, + as_str(charset), + ); + current_block = 17788412896529399552; + } + } else { + current_block = 17788412896529399552; + } + match current_block { + 8795901732489102124 => {} + _ => { + /* check header directly as is_send_by_messenger is not yet set up */ + let is_msgrmsg: libc::c_int = (dc_mimeparser_lookup_optional_field( + &mimeparser, + b"Chat-Version\x00" as *const u8 as *const libc::c_char, + ) != 0 as *mut libc::c_void + as *mut mailimf_optional_field) + as libc::c_int; + let simplified_txt: *mut libc::c_char = + simplifier.unwrap().simplify( + decoded_data, + decoded_data_bytes as libc::c_int, + if mime_type == 70i32 { 1i32 } else { 0i32 }, + is_msgrmsg, + ); + if !simplified_txt.is_null() + && 0 != *simplified_txt.offset(0isize) as libc::c_int + { + part = dc_mimepart_new(); + (*part).type_0 = 10i32; + (*part).int_mimetype = mime_type; + (*part).msg = simplified_txt; + (*part).msg_raw = + strndup(decoded_data, decoded_data_bytes as libc::c_ulong); + do_add_single_part(mimeparser, part); + part = 0 as *mut dc_mimepart_t + } else { + free(simplified_txt as *mut libc::c_void); } + if 0 != simplifier.unwrap().is_forwarded { + (*mimeparser).is_forwarded = 1i32 + } + current_block = 10261677128829721533; + } + } } 80 | 90 | 100 | 110 | 111 => { /* try to get file name from diff --git a/src/dc_simplify.rs b/src/dc_simplify.rs index 6ee4c63de..cf802461b 100644 --- a/src/dc_simplify.rs +++ b/src/dc_simplify.rs @@ -20,216 +20,216 @@ impl dc_simplify_t { } } -pub unsafe fn simplify( - &mut self, - in_unterminated: *const libc::c_char, - in_bytes: libc::c_int, - is_html: libc::c_int, - is_msgrmsg: libc::c_int, -) -> *mut libc::c_char { - /* create a copy of the given buffer */ - let mut out: *mut libc::c_char; - let mut temp: *mut libc::c_char; - self.is_forwarded = 0i32; - self.is_cut_at_begin = 0i32; - self.is_cut_at_end = 0i32; - out = strndup( - in_unterminated as *mut libc::c_char, - in_bytes as libc::c_ulong, - ); - if out.is_null() { - return dc_strdup(b"\x00" as *const u8 as *const libc::c_char); - } - if 0 != is_html { - temp = dc_dehtml(out); + pub unsafe fn simplify( + &mut self, + in_unterminated: *const libc::c_char, + in_bytes: libc::c_int, + is_html: libc::c_int, + is_msgrmsg: libc::c_int, + ) -> *mut libc::c_char { + /* create a copy of the given buffer */ + let mut out: *mut libc::c_char; + let mut temp: *mut libc::c_char; + self.is_forwarded = 0i32; + self.is_cut_at_begin = 0i32; + self.is_cut_at_end = 0i32; + out = strndup( + in_unterminated as *mut libc::c_char, + in_bytes as libc::c_ulong, + ); + if out.is_null() { + return dc_strdup(b"\x00" as *const u8 as *const libc::c_char); + } + if 0 != is_html { + temp = dc_dehtml(out); + if !temp.is_null() { + free(out as *mut libc::c_void); + out = temp + } + } + dc_remove_cr_chars(out); + temp = self.simplify_plain_text(out, is_msgrmsg); if !temp.is_null() { free(out as *mut libc::c_void); out = temp } - } - dc_remove_cr_chars(out); - temp = self.simplify_plain_text(out, is_msgrmsg); - if !temp.is_null() { - free(out as *mut libc::c_void); - out = temp - } - dc_remove_cr_chars(out); + dc_remove_cr_chars(out); - out -} + out + } -/** - * Simplify Plain Text - */ -unsafe fn simplify_plain_text( - &mut self, - buf_terminated: *const libc::c_char, - is_msgrmsg: libc::c_int, -) -> *mut libc::c_char { - /* This function ... - ... removes all text after the line `-- ` (footer mark) - ... removes full quotes at the beginning and at the end of the text - - these are all lines starting with the character `>` - ... remove a non-empty line before the removed quote (contains sth. like "On 2.9.2016, Bjoern wrote:" in different formats and lanugages) */ - /* split the given buffer into lines */ - let lines: *mut carray = dc_split_into_lines(buf_terminated); - let mut l: libc::c_int; - let mut l_first: libc::c_int = 0i32; - /* if l_last is -1, there are no lines */ - let mut l_last: libc::c_int = - carray_count(lines).wrapping_sub(1i32 as libc::c_uint) as libc::c_int; - let mut line: *mut libc::c_char; - let mut footer_mark: libc::c_int = 0i32; - l = l_first; - while l <= l_last { - line = carray_get(lines, l as libc::c_uint) as *mut libc::c_char; - if strcmp(line, b"-- \x00" as *const u8 as *const libc::c_char) == 0i32 - || strcmp(line, b"-- \x00" as *const u8 as *const libc::c_char) == 0i32 - { - footer_mark = 1i32 - } - if strcmp(line, b"--\x00" as *const u8 as *const libc::c_char) == 0i32 - || strcmp(line, b"---\x00" as *const u8 as *const libc::c_char) == 0i32 - || strcmp(line, b"----\x00" as *const u8 as *const libc::c_char) == 0i32 - { - footer_mark = 1i32; - self.is_cut_at_end = 1i32 - } - if 0 != footer_mark { - l_last = l - 1i32; - /* done */ - break; - } else { - l += 1 - } - } - if l_last - l_first + 1i32 >= 3i32 { - let line0: *mut libc::c_char = - carray_get(lines, l_first as libc::c_uint) as *mut libc::c_char; - let line1: *mut libc::c_char = - carray_get(lines, (l_first + 1i32) as libc::c_uint) as *mut libc::c_char; - let line2: *mut libc::c_char = - carray_get(lines, (l_first + 2i32) as libc::c_uint) as *mut libc::c_char; - if strcmp( - line0, - b"---------- Forwarded message ----------\x00" as *const u8 as *const libc::c_char, - ) == 0i32 - && strncmp(line1, b"From: \x00" as *const u8 as *const libc::c_char, 6) == 0i32 - && *line2.offset(0isize) as libc::c_int == 0i32 - { - self.is_forwarded = 1i32; - l_first += 3i32 - } - } - l = l_first; - while l <= l_last { - line = carray_get(lines, l as libc::c_uint) as *mut libc::c_char; - if strncmp(line, b"-----\x00" as *const u8 as *const libc::c_char, 5) == 0i32 - || strncmp(line, b"_____\x00" as *const u8 as *const libc::c_char, 5) == 0i32 - || strncmp(line, b"=====\x00" as *const u8 as *const libc::c_char, 5) == 0i32 - || strncmp(line, b"*****\x00" as *const u8 as *const libc::c_char, 5) == 0i32 - || strncmp(line, b"~~~~~\x00" as *const u8 as *const libc::c_char, 5) == 0i32 - { - l_last = l - 1i32; - self.is_cut_at_end = 1i32; - /* done */ - break; - } else { - l += 1 - } - } - if 0 == is_msgrmsg { - let mut l_lastQuotedLine: libc::c_int = -1i32; - l = l_last; - while l >= l_first { - line = carray_get(lines, l as libc::c_uint) as *mut libc::c_char; - if is_plain_quote(line) { - l_lastQuotedLine = l - } else if !is_empty_line(line) { - break; - } - l -= 1 - } - if l_lastQuotedLine != -1i32 { - l_last = l_lastQuotedLine - 1i32; - self.is_cut_at_end = 1i32; - if l_last > 0i32 { - if is_empty_line(carray_get(lines, l_last as libc::c_uint) as *mut libc::c_char) - { - l_last -= 1 - } - } - if l_last > 0i32 { - line = carray_get(lines, l_last as libc::c_uint) as *mut libc::c_char; - if is_quoted_headline(line) { - l_last -= 1 - } - } - } - } - if 0 == is_msgrmsg { - let mut l_lastQuotedLine_0: libc::c_int = -1i32; - let mut hasQuotedHeadline: libc::c_int = 0i32; + /** + * Simplify Plain Text + */ + unsafe fn simplify_plain_text( + &mut self, + buf_terminated: *const libc::c_char, + is_msgrmsg: libc::c_int, + ) -> *mut libc::c_char { + /* This function ... + ... removes all text after the line `-- ` (footer mark) + ... removes full quotes at the beginning and at the end of the text - + these are all lines starting with the character `>` + ... remove a non-empty line before the removed quote (contains sth. like "On 2.9.2016, Bjoern wrote:" in different formats and lanugages) */ + /* split the given buffer into lines */ + let lines: *mut carray = dc_split_into_lines(buf_terminated); + let mut l: libc::c_int; + let mut l_first: libc::c_int = 0i32; + /* if l_last is -1, there are no lines */ + let mut l_last: libc::c_int = + carray_count(lines).wrapping_sub(1i32 as libc::c_uint) as libc::c_int; + let mut line: *mut libc::c_char; + let mut footer_mark: libc::c_int = 0i32; l = l_first; while l <= l_last { line = carray_get(lines, l as libc::c_uint) as *mut libc::c_char; - if is_plain_quote(line) { - l_lastQuotedLine_0 = l - } else if !is_empty_line(line) { - if is_quoted_headline(line) - && 0 == hasQuotedHeadline - && l_lastQuotedLine_0 == -1i32 - { - hasQuotedHeadline = 1i32 - } else { - /* non-quoting line found */ + if strcmp(line, b"-- \x00" as *const u8 as *const libc::c_char) == 0i32 + || strcmp(line, b"-- \x00" as *const u8 as *const libc::c_char) == 0i32 + { + footer_mark = 1i32 + } + if strcmp(line, b"--\x00" as *const u8 as *const libc::c_char) == 0i32 + || strcmp(line, b"---\x00" as *const u8 as *const libc::c_char) == 0i32 + || strcmp(line, b"----\x00" as *const u8 as *const libc::c_char) == 0i32 + { + footer_mark = 1i32; + self.is_cut_at_end = 1i32 + } + if 0 != footer_mark { + l_last = l - 1i32; + /* done */ + break; + } else { + l += 1 + } + } + if l_last - l_first + 1i32 >= 3i32 { + let line0: *mut libc::c_char = + carray_get(lines, l_first as libc::c_uint) as *mut libc::c_char; + let line1: *mut libc::c_char = + carray_get(lines, (l_first + 1i32) as libc::c_uint) as *mut libc::c_char; + let line2: *mut libc::c_char = + carray_get(lines, (l_first + 2i32) as libc::c_uint) as *mut libc::c_char; + if strcmp( + line0, + b"---------- Forwarded message ----------\x00" as *const u8 as *const libc::c_char, + ) == 0i32 + && strncmp(line1, b"From: \x00" as *const u8 as *const libc::c_char, 6) == 0i32 + && *line2.offset(0isize) as libc::c_int == 0i32 + { + self.is_forwarded = 1i32; + l_first += 3i32 + } + } + l = l_first; + while l <= l_last { + line = carray_get(lines, l as libc::c_uint) as *mut libc::c_char; + if strncmp(line, b"-----\x00" as *const u8 as *const libc::c_char, 5) == 0i32 + || strncmp(line, b"_____\x00" as *const u8 as *const libc::c_char, 5) == 0i32 + || strncmp(line, b"=====\x00" as *const u8 as *const libc::c_char, 5) == 0i32 + || strncmp(line, b"*****\x00" as *const u8 as *const libc::c_char, 5) == 0i32 + || strncmp(line, b"~~~~~\x00" as *const u8 as *const libc::c_char, 5) == 0i32 + { + l_last = l - 1i32; + self.is_cut_at_end = 1i32; + /* done */ + break; + } else { + l += 1 + } + } + if 0 == is_msgrmsg { + let mut l_lastQuotedLine: libc::c_int = -1i32; + l = l_last; + while l >= l_first { + line = carray_get(lines, l as libc::c_uint) as *mut libc::c_char; + if is_plain_quote(line) { + l_lastQuotedLine = l + } else if !is_empty_line(line) { break; } + l -= 1 + } + if l_lastQuotedLine != -1i32 { + l_last = l_lastQuotedLine - 1i32; + self.is_cut_at_end = 1i32; + if l_last > 0i32 { + if is_empty_line(carray_get(lines, l_last as libc::c_uint) as *mut libc::c_char) + { + l_last -= 1 + } + } + if l_last > 0i32 { + line = carray_get(lines, l_last as libc::c_uint) as *mut libc::c_char; + if is_quoted_headline(line) { + l_last -= 1 + } + } + } + } + if 0 == is_msgrmsg { + let mut l_lastQuotedLine_0: libc::c_int = -1i32; + let mut hasQuotedHeadline: libc::c_int = 0i32; + l = l_first; + while l <= l_last { + line = carray_get(lines, l as libc::c_uint) as *mut libc::c_char; + if is_plain_quote(line) { + l_lastQuotedLine_0 = l + } else if !is_empty_line(line) { + if is_quoted_headline(line) + && 0 == hasQuotedHeadline + && l_lastQuotedLine_0 == -1i32 + { + hasQuotedHeadline = 1i32 + } else { + /* non-quoting line found */ + break; + } + } + l += 1 + } + if l_lastQuotedLine_0 != -1i32 { + l_first = l_lastQuotedLine_0 + 1i32; + self.is_cut_at_begin = 1i32 + } + } + /* re-create buffer from the remaining lines */ + let mut ret = String::new(); + if 0 != self.is_cut_at_begin { + ret += "[...]"; + } + /* we write empty lines only in case and non-empty line follows */ + let mut pending_linebreaks: libc::c_int = 0i32; + let mut content_lines_added: libc::c_int = 0i32; + l = l_first; + while l <= l_last { + line = carray_get(lines, l as libc::c_uint) as *mut libc::c_char; + if is_empty_line(line) { + pending_linebreaks += 1 + } else { + if 0 != content_lines_added { + if pending_linebreaks > 2i32 { + pending_linebreaks = 2i32 + } + while 0 != pending_linebreaks { + ret += "\n"; + pending_linebreaks -= 1 + } + } + // the incoming message might contain invalid UTF8 + ret += &to_string_lossy(line); + content_lines_added += 1; + pending_linebreaks = 1i32 } l += 1 } - if l_lastQuotedLine_0 != -1i32 { - l_first = l_lastQuotedLine_0 + 1i32; - self.is_cut_at_begin = 1i32 + if 0 != self.is_cut_at_end && (0 == self.is_cut_at_begin || 0 != content_lines_added) { + ret += " [...]"; } - } - /* re-create buffer from the remaining lines */ - let mut ret = String::new(); - if 0 != self.is_cut_at_begin { - ret += "[...]"; - } - /* we write empty lines only in case and non-empty line follows */ - let mut pending_linebreaks: libc::c_int = 0i32; - let mut content_lines_added: libc::c_int = 0i32; - l = l_first; - while l <= l_last { - line = carray_get(lines, l as libc::c_uint) as *mut libc::c_char; - if is_empty_line(line) { - pending_linebreaks += 1 - } else { - if 0 != content_lines_added { - if pending_linebreaks > 2i32 { - pending_linebreaks = 2i32 - } - while 0 != pending_linebreaks { - ret += "\n"; - pending_linebreaks -= 1 - } - } - // the incoming message might contain invalid UTF8 - ret += &to_string_lossy(line); - content_lines_added += 1; - pending_linebreaks = 1i32 - } - l += 1 - } - if 0 != self.is_cut_at_end && (0 == self.is_cut_at_begin || 0 != content_lines_added) { - ret += " [...]"; - } - dc_free_splitted_lines(lines); + dc_free_splitted_lines(lines); - to_cstring(ret) -} + to_cstring(ret) + } } /* Simplify and normalise text: Remove quotes, signatures, unnecessary