remove duplicate code and possibly a leak

This commit is contained in:
holger krekel
2019-09-29 13:55:45 +02:00
parent 064337b5d3
commit 18030fa61e
4 changed files with 57 additions and 100 deletions

View File

@@ -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 { match (*data).dt_type {
0 => { 0 => {
println!( println!(

View File

@@ -5,14 +5,12 @@ use std::ptr;
use charset::Charset; use charset::Charset;
use deltachat_derive::{FromSql, ToSql}; use deltachat_derive::{FromSql, ToSql};
use libc::{strcmp, strlen, strncmp}; use libc::{strcmp, strlen, strncmp};
use mmime::display::display_mime;
use mmime::mailimf::types::*; use mmime::mailimf::types::*;
use mmime::mailimf::*; use mmime::mailimf::*;
use mmime::mailmime::content::*; use mmime::mailmime::content::*;
use mmime::mailmime::disposition::*; use mmime::mailmime::disposition::*;
use mmime::mailmime::types::*; use mmime::mailmime::types::*;
use mmime::mailmime::*; use mmime::mailmime::*;
use mmime::mmapstring::*;
use mmime::other::*; use mmime::other::*;
use crate::constants::Viewtype; use crate::constants::Viewtype;
@@ -26,6 +24,7 @@ use crate::error::Error;
use crate::location; use crate::location;
use crate::param::*; use crate::param::*;
use crate::stock::StockMessage; use crate::stock::StockMessage;
use crate::wrapmime;
#[derive(Debug)] #[derive(Debug)]
pub struct MimeParser<'a> { pub struct MimeParser<'a> {
@@ -1155,61 +1154,15 @@ pub unsafe fn mailmime_find_ct_parameter(
ptr::null_mut() ptr::null_mut()
} }
pub unsafe fn mailmime_transfer_decode(mime: *mut Mailmime) -> Result<Vec<u8>, Error> { pub fn mailmime_transfer_decode(mime: *mut Mailmime) -> Result<Vec<u8>, Error> {
ensure!(!mime.is_null(), "invalid inputs"); 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) let mime_data = unsafe { (*mime).mm_data.mm_single };
.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"))
wrapmime::decode_dt_data(mime_data, mime_transfer_encoding)
} }
pub fn mailimf_get_recipients(imffields: *mut mailimf_fields) -> HashSet<String> { pub fn mailimf_get_recipients(imffields: *mut mailimf_fields) -> HashSet<String> {

View File

@@ -600,22 +600,16 @@ fn decrypt_part(
mime_transfer_encoding = enc; mime_transfer_encoding = enc;
} }
let (decoded_data, decoded_data_bytes) = let data: Vec<u8> = wrapmime::decode_dt_data(mime_data, mime_transfer_encoding)?;
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(); let mut ret_decrypted_mime = ptr::null_mut();
ensure!(!decoded_data.is_null(), "Missing data"); if has_decrypted_pgp_armor(&data) {
let data = unsafe { std::slice::from_raw_parts(decoded_data as *const u8, decoded_data_bytes) };
if has_decrypted_pgp_armor(data) {
// we should only have one decryption happening // we should only have one decryption happening
ensure!(ret_valid_signatures.is_empty(), "corrupt signatures"); ensure!(ret_valid_signatures.is_empty(), "corrupt signatures");
let plain = match dc_pgp_pk_decrypt( let plain = match dc_pgp_pk_decrypt(
data, &data,
&private_keyring, &private_keyring,
&public_keyring_for_validate, &public_keyring_for_validate,
Some(ret_valid_signatures), Some(ret_valid_signatures),
@@ -624,10 +618,7 @@ fn decrypt_part(
ensure!(!ret_valid_signatures.is_empty(), "no valid signatures"); ensure!(!ret_valid_signatures.is_empty(), "no valid signatures");
plain plain
} }
Err(err) => { Err(err) => bail!("could not decrypt: {}", err),
unsafe { mmap_string_unref(decoded_data) };
bail!("could not decrypt: {}", err)
}
}; };
let plain_bytes = plain.len(); let plain_bytes = plain.len();
let plain_buf = plain.as_ptr() as *const libc::c_char; let plain_buf = plain.as_ptr() as *const libc::c_char;
@@ -655,7 +646,6 @@ fn decrypt_part(
ret_decrypted_mime = decrypted_mime; ret_decrypted_mime = decrypted_mime;
} }
} }
unsafe { mmap_string_unref(decoded_data) };
Ok(ret_decrypted_mime) Ok(ret_decrypted_mime)
} }

View File

@@ -4,6 +4,7 @@ use std::ptr;
use crate::dc_tools::*; use crate::dc_tools::*;
use crate::error::Error; use crate::error::Error;
use mmime::clist::*; use mmime::clist::*;
use mmime::display::*;
use mmime::mailimf::types::*; use mmime::mailimf::types::*;
use mmime::mailimf::types_helper::*; use mmime::mailimf::types_helper::*;
use mmime::mailmime::content::*; use mmime::mailmime::content::*;
@@ -11,6 +12,7 @@ use mmime::mailmime::disposition::*;
use mmime::mailmime::types::*; use mmime::mailmime::types::*;
use mmime::mailmime::types_helper::*; use mmime::mailmime::types_helper::*;
use mmime::mailmime::*; use mmime::mailmime::*;
use mmime::mmapstring::*;
use mmime::other::*; use mmime::other::*;
#[macro_export] #[macro_export]
@@ -108,48 +110,60 @@ pub fn get_mime_transfer_encoding(mime: *mut Mailmime) -> Option<libc::c_int> {
pub fn decode_dt_data( pub fn decode_dt_data(
mime_data: *mut mailmime_data, mime_data: *mut mailmime_data,
mime_transfer_encoding: libc::c_int, mime_transfer_encoding: libc::c_int,
) -> Result<(*mut libc::c_char, libc::size_t), Error> { ) -> Result<Vec<u8>, Error> {
// Decode data according to mime_transfer_encoding // Decode data according to mime_transfer_encoding
// returns Ok with a (decoded_data,decoded_data_bytes) pointer // returns Ok with a (decoded_data,decoded_data_bytes) pointer
// where the caller must make sure to free it. // where the caller must make sure to free it.
// It may return Ok(ptr::null_mut(), 0) // 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 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_8BIT as libc::c_int
|| mime_transfer_encoding == MAILMIME_MECHANISM_BINARY as libc::c_int || mime_transfer_encoding == MAILMIME_MECHANISM_BINARY as libc::c_int
{ {
unsafe { let decoded_data = unsafe { (*mime_data).dt_data.dt_text.dt_data };
decoded_data = (*mime_data).dt_data.dt_text.dt_data as *mut _; let decoded_data_bytes = unsafe { (*mime_data).dt_data.dt_text.dt_length };
decoded_data_bytes = (*mime_data).dt_data.dt_text.dt_length;
} if decoded_data.is_null() || decoded_data_bytes <= 0 {
ensure!( bail!("No data to decode found");
!decoded_data.is_null() && decoded_data_bytes > 0, } else {
"could not decode mime message" let result = unsafe {
); std::slice::from_raw_parts(decoded_data as *const u8, decoded_data_bytes)
} else { };
let mut current_index: libc::size_t = 0; return Ok(result.to_vec());
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;
} }
} }
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"))
} }
/************************************** /**************************************