diff --git a/mmime/src/display.rs b/mmime/src/display.rs index 8851c4eb5..3a895df7b 100644 --- a/mmime/src/display.rs +++ b/mmime/src/display.rs @@ -123,7 +123,7 @@ unsafe fn display_mime_discrete_type(mut discrete_type: *mut mailmime_discrete_t _ => {} }; } -unsafe fn display_mime_data(mut data: *mut mailmime_data) { +pub unsafe fn display_mime_data(mut data: *mut mailmime_data) { match (*data).dt_type { 0 => { println!( diff --git a/src/dc_mimeparser.rs b/src/dc_mimeparser.rs index 0d6a8fb85..35e889ace 100644 --- a/src/dc_mimeparser.rs +++ b/src/dc_mimeparser.rs @@ -5,14 +5,12 @@ use std::ptr; use charset::Charset; use deltachat_derive::{FromSql, ToSql}; use libc::{strcmp, strlen, strncmp}; -use mmime::display::display_mime; use mmime::mailimf::types::*; use mmime::mailimf::*; use mmime::mailmime::content::*; use mmime::mailmime::disposition::*; use mmime::mailmime::types::*; use mmime::mailmime::*; -use mmime::mmapstring::*; use mmime::other::*; use crate::constants::Viewtype; @@ -26,6 +24,7 @@ use crate::error::Error; use crate::location; use crate::param::*; use crate::stock::StockMessage; +use crate::wrapmime; #[derive(Debug)] pub struct MimeParser<'a> { @@ -1155,61 +1154,15 @@ pub unsafe fn mailmime_find_ct_parameter( ptr::null_mut() } -pub unsafe fn mailmime_transfer_decode(mime: *mut Mailmime) -> Result, Error> { +pub fn mailmime_transfer_decode(mime: *mut Mailmime) -> Result, Error> { ensure!(!mime.is_null(), "invalid inputs"); - let mut mime_transfer_encoding = MAILMIME_MECHANISM_BINARY as libc::c_int; + let mime_transfer_encoding = + wrapmime::get_mime_transfer_encoding(mime).unwrap_or(MAILMIME_MECHANISM_BINARY as i32); - let mime_transfer_encoding = wrapmime::get_mime_transfer_encoding(mmime) - .unwrap_or(MAILMIME_MECHANISM_BINARY); - let mime_data = (*mime).mm_data.mm_single; - - if mime_transfer_encoding == MAILMIME_MECHANISM_7BIT as libc::c_int - || mime_transfer_encoding == MAILMIME_MECHANISM_8BIT as libc::c_int - || mime_transfer_encoding == MAILMIME_MECHANISM_BINARY as libc::c_int - { - let decoded_data = (*mime_data).dt_data.dt_text.dt_data; - let decoded_data_bytes = (*mime_data).dt_data.dt_text.dt_length; - - if decoded_data.is_null() || decoded_data_bytes <= 0 { - bail!("No data to decode found"); - } else { - let result = std::slice::from_raw_parts(decoded_data as *const u8, decoded_data_bytes); - return Ok(result.to_vec()); - } - } - display_mime(mime); - - let mut current_index = 0; - let mut transfer_decoding_buffer = ptr::null_mut(); - let mut decoded_data_bytes = 0; - - let r = mailmime_part_parse( - (*mime_data).dt_data.dt_text.dt_data, - (*mime_data).dt_data.dt_text.dt_length, - &mut current_index, - mime_transfer_encoding, - &mut transfer_decoding_buffer, - &mut decoded_data_bytes, - ); - - if r == MAILIMF_NO_ERROR as libc::c_int - && !transfer_decoding_buffer.is_null() - && decoded_data_bytes > 0 - { - let result = - std::slice::from_raw_parts(transfer_decoding_buffer as *const u8, decoded_data_bytes) - .to_vec(); - // we return a fresh vec and transfer_decoding_buffer is not used or passed anywhere - // so it's safe to free it right away, as mailman_part_parse has - // allocated it fresh. - mmap_string_unref(transfer_decoding_buffer); - - return Ok(result); - } - - Err(format_err!("Failed to to decode")) + let mime_data = unsafe { (*mime).mm_data.mm_single }; + wrapmime::decode_dt_data(mime_data, mime_transfer_encoding) } pub fn mailimf_get_recipients(imffields: *mut mailimf_fields) -> HashSet { diff --git a/src/e2ee.rs b/src/e2ee.rs index 1e7ae3820..5c702fb6c 100644 --- a/src/e2ee.rs +++ b/src/e2ee.rs @@ -600,22 +600,16 @@ fn decrypt_part( mime_transfer_encoding = enc; } - let (decoded_data, decoded_data_bytes) = - wrapmime::decode_dt_data(mime_data, mime_transfer_encoding)?; + let data: Vec = wrapmime::decode_dt_data(mime_data, mime_transfer_encoding)?; - // encrypted, non-NULL decoded data in decoded_data now ... - // Note that we need to take care of freeing decoded_data ourself, - // after encryption has been attempted. let mut ret_decrypted_mime = ptr::null_mut(); - ensure!(!decoded_data.is_null(), "Missing data"); - let data = unsafe { std::slice::from_raw_parts(decoded_data as *const u8, decoded_data_bytes) }; - if has_decrypted_pgp_armor(data) { + if has_decrypted_pgp_armor(&data) { // we should only have one decryption happening ensure!(ret_valid_signatures.is_empty(), "corrupt signatures"); let plain = match dc_pgp_pk_decrypt( - data, + &data, &private_keyring, &public_keyring_for_validate, Some(ret_valid_signatures), @@ -624,10 +618,7 @@ fn decrypt_part( ensure!(!ret_valid_signatures.is_empty(), "no valid signatures"); plain } - Err(err) => { - unsafe { mmap_string_unref(decoded_data) }; - bail!("could not decrypt: {}", err) - } + Err(err) => bail!("could not decrypt: {}", err), }; let plain_bytes = plain.len(); let plain_buf = plain.as_ptr() as *const libc::c_char; @@ -655,7 +646,6 @@ fn decrypt_part( ret_decrypted_mime = decrypted_mime; } } - unsafe { mmap_string_unref(decoded_data) }; Ok(ret_decrypted_mime) } diff --git a/src/wrapmime.rs b/src/wrapmime.rs index fa1f900e0..07afb1e75 100644 --- a/src/wrapmime.rs +++ b/src/wrapmime.rs @@ -4,6 +4,7 @@ use std::ptr; use crate::dc_tools::*; use crate::error::Error; use mmime::clist::*; +use mmime::display::*; use mmime::mailimf::types::*; use mmime::mailimf::types_helper::*; use mmime::mailmime::content::*; @@ -11,6 +12,7 @@ use mmime::mailmime::disposition::*; use mmime::mailmime::types::*; use mmime::mailmime::types_helper::*; use mmime::mailmime::*; +use mmime::mmapstring::*; use mmime::other::*; #[macro_export] @@ -108,48 +110,60 @@ pub fn get_mime_transfer_encoding(mime: *mut Mailmime) -> Option { pub fn decode_dt_data( mime_data: *mut mailmime_data, mime_transfer_encoding: libc::c_int, -) -> Result<(*mut libc::c_char, libc::size_t), Error> { +) -> Result, Error> { // Decode data according to mime_transfer_encoding // returns Ok with a (decoded_data,decoded_data_bytes) pointer // where the caller must make sure to free it. // It may return Ok(ptr::null_mut(), 0) - - let mut transfer_decoding_buffer: *mut libc::c_char = ptr::null_mut(); - let decoded_data: *mut libc::c_char; - let mut decoded_data_bytes: libc::size_t = 0; if mime_transfer_encoding == MAILMIME_MECHANISM_7BIT as libc::c_int || mime_transfer_encoding == MAILMIME_MECHANISM_8BIT as libc::c_int || mime_transfer_encoding == MAILMIME_MECHANISM_BINARY as libc::c_int { - unsafe { - decoded_data = (*mime_data).dt_data.dt_text.dt_data as *mut _; - decoded_data_bytes = (*mime_data).dt_data.dt_text.dt_length; - } - ensure!( - !decoded_data.is_null() && decoded_data_bytes > 0, - "could not decode mime message" - ); - } else { - let mut current_index: libc::size_t = 0; - unsafe { - let r = mailmime_part_parse( - (*mime_data).dt_data.dt_text.dt_data, - (*mime_data).dt_data.dt_text.dt_length, - &mut current_index, - mime_transfer_encoding, - &mut transfer_decoding_buffer, - &mut decoded_data_bytes, - ); - if r != MAILIMF_NO_ERROR as libc::c_int - || transfer_decoding_buffer.is_null() - || decoded_data_bytes <= 0 - { - bail!("mailmime_part_parse returned error or invalid data"); - } - decoded_data = transfer_decoding_buffer; + let decoded_data = unsafe { (*mime_data).dt_data.dt_text.dt_data }; + let decoded_data_bytes = unsafe { (*mime_data).dt_data.dt_text.dt_length }; + + if decoded_data.is_null() || decoded_data_bytes <= 0 { + bail!("No data to decode found"); + } else { + let result = unsafe { + std::slice::from_raw_parts(decoded_data as *const u8, decoded_data_bytes) + }; + return Ok(result.to_vec()); } } - Ok((decoded_data, decoded_data_bytes)) + unsafe { display_mime_data(mime_data) }; + + let mut current_index = 0; + let mut transfer_decoding_buffer = ptr::null_mut(); + let mut decoded_data_bytes = 0; + + let r = unsafe { mailmime_part_parse( + (*mime_data).dt_data.dt_text.dt_data, + (*mime_data).dt_data.dt_text.dt_length, + &mut current_index, + mime_transfer_encoding, + &mut transfer_decoding_buffer, + &mut decoded_data_bytes, + ) }; + + if r == MAILIMF_NO_ERROR as libc::c_int + && !transfer_decoding_buffer.is_null() + && decoded_data_bytes > 0 + { + let result = unsafe { std::slice::from_raw_parts( + transfer_decoding_buffer as *const u8, + decoded_data_bytes, + ) } + .to_vec(); + // we return a fresh vec and transfer_decoding_buffer is not used or passed anywhere + // so it's safe to free it right away, as mailman_part_parse has + // allocated it fresh. + unsafe { mmap_string_unref(transfer_decoding_buffer) }; + + return Ok(result); + } + + Err(format_err!("Failed to to decode")) } /**************************************