no more memory corruption

This commit is contained in:
dignifiedquire
2019-09-29 17:41:04 -06:00
parent 416a1751a2
commit 5c6df6dbf6
11 changed files with 250 additions and 313 deletions

View File

@@ -214,12 +214,7 @@ pub unsafe fn mailimf_fields_parse(
Some(mailimf_field_parse), Some(mailimf_field_parse),
None, None,
); );
/*
if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE)) {
res = r;
goto err;
}
*/
match r { match r {
0 => { 0 => {
/* do nothing */ /* do nothing */
@@ -274,7 +269,6 @@ unsafe fn mailimf_field_parse(
let mut subject = 0 as *mut mailimf_subject; let mut subject = 0 as *mut mailimf_subject;
let mut comments = 0 as *mut mailimf_comments; let mut comments = 0 as *mut mailimf_comments;
let mut keywords = 0 as *mut mailimf_keywords; let mut keywords = 0 as *mut mailimf_keywords;
let mut optional_field = 0 as *mut mailimf_optional_field;
let guessed_type = guess_header_type(message, length, cur_token); let guessed_type = guess_header_type(message, length, cur_token);
@@ -519,62 +513,54 @@ unsafe fn mailimf_field_parse(
} }
if try_optional { if try_optional {
r = mailimf_optional_field_parse(message, length, &mut cur_token, &mut optional_field); match mailimf_optional_field_parse(message, length, &mut cur_token) {
if r != MAILIMF_NO_ERROR as libc::c_int { Ok(value) => {
return Err(r);
}
*indx = cur_token; *indx = cur_token;
return Ok(mailimf_field::OptionalField(optional_field)); return Ok(mailimf_field::OptionalField(value));
}
Err(r) => return Err(r),
}
} }
Err(res) Err(res)
} }
unsafe fn mailimf_optional_field_parse( unsafe fn mailimf_optional_field_parse(
mut message: *const libc::c_char, message: *const libc::c_char,
mut length: size_t, length: size_t,
mut indx: *mut size_t, indx: *mut size_t,
mut result: *mut *mut mailimf_optional_field, ) -> Result<*mut mailimf_optional_field, libc::c_int> {
) -> libc::c_int {
let mut name: *mut libc::c_char = 0 as *mut libc::c_char; let mut name: *mut libc::c_char = 0 as *mut libc::c_char;
let mut value: *mut libc::c_char = 0 as *mut libc::c_char; let mut value: *mut libc::c_char = 0 as *mut libc::c_char;
let mut optional_field: *mut mailimf_optional_field = 0 as *mut mailimf_optional_field;
let mut cur_token: size_t = 0;
let mut r: libc::c_int = 0;
let mut res: libc::c_int = 0; let mut res: libc::c_int = 0;
cur_token = *indx; let mut cur_token = *indx;
r = mailimf_field_name_parse(message, length, &mut cur_token, &mut name);
let r = mailimf_field_name_parse(message, length, &mut cur_token, &mut name);
if r != MAILIMF_NO_ERROR as libc::c_int { if r != MAILIMF_NO_ERROR as libc::c_int {
res = r
} else {
r = mailimf_colon_parse(message, length, &mut cur_token);
if r != MAILIMF_NO_ERROR as libc::c_int {
res = r
} else {
r = mailimf_unstructured_parse(message, length, &mut cur_token, &mut value);
if r != MAILIMF_NO_ERROR as libc::c_int {
res = r
} else {
r = mailimf_unstrict_crlf_parse(message, length, &mut cur_token);
if r != MAILIMF_NO_ERROR as libc::c_int {
res = r
} else {
optional_field = mailimf_optional_field_new(name, value);
if optional_field.is_null() {
res = MAILIMF_ERROR_MEMORY as libc::c_int
} else {
*result = optional_field;
*indx = cur_token;
return MAILIMF_NO_ERROR as libc::c_int;
}
}
mailimf_unstructured_free(value);
}
}
mailimf_field_name_free(name); mailimf_field_name_free(name);
return Err(r);
} }
return res; let r = mailimf_colon_parse(message, length, &mut cur_token);
if r != MAILIMF_NO_ERROR as libc::c_int {
mailimf_field_name_free(name);
return Err(r);
} }
let r = mailimf_unstructured_parse(message, length, &mut cur_token, &mut value);
if r != MAILIMF_NO_ERROR as libc::c_int {
mailimf_unstructured_free(value);
mailimf_field_name_free(name);
return Err(r);
}
let r = mailimf_unstrict_crlf_parse(message, length, &mut cur_token);
if r != MAILIMF_NO_ERROR as libc::c_int {
mailimf_unstructured_free(value);
mailimf_field_name_free(name);
return Err(r);
}
*indx = cur_token;
Ok(mailimf_optional_field_new(name, value))
}
unsafe fn mailimf_unstrict_crlf_parse( unsafe fn mailimf_unstrict_crlf_parse(
mut message: *const libc::c_char, mut message: *const libc::c_char,
mut length: size_t, mut length: size_t,
@@ -1006,11 +992,12 @@ pub unsafe fn mailimf_unstrict_char_parse(
*indx = cur_token; *indx = cur_token;
return MAILIMF_NO_ERROR as libc::c_int; return MAILIMF_NO_ERROR as libc::c_int;
} }
unsafe fn mailimf_field_name_parse( unsafe fn mailimf_field_name_parse(
mut message: *const libc::c_char, message: *const libc::c_char,
mut length: size_t, length: size_t,
mut indx: *mut size_t, indx: *mut size_t,
mut result: *mut *mut libc::c_char, result: &mut *mut libc::c_char,
) -> libc::c_int { ) -> libc::c_int {
let mut field_name: *mut libc::c_char = 0 as *mut libc::c_char; let mut field_name: *mut libc::c_char = 0 as *mut libc::c_char;
let mut cur_token: size_t = 0; let mut cur_token: size_t = 0;
@@ -1045,8 +1032,9 @@ unsafe fn mailimf_field_name_parse(
cur_token = end; cur_token = end;
*indx = cur_token; *indx = cur_token;
*result = field_name; *result = field_name;
return MAILIMF_NO_ERROR as libc::c_int; MAILIMF_NO_ERROR as libc::c_int
} }
/* /*
field-name = 1*ftext field-name = 1*ftext
*/ */
@@ -4136,7 +4124,7 @@ pub unsafe fn mailimf_atom_parse(
} }
return res; return res;
} }
unsafe fn mailimf_struct_multiple_parse<T>( unsafe fn mailimf_struct_multiple_parse<T: std::fmt::Debug>(
mut message: *const libc::c_char, mut message: *const libc::c_char,
mut length: size_t, mut length: size_t,
mut indx: *mut size_t, mut indx: *mut size_t,
@@ -4146,27 +4134,27 @@ unsafe fn mailimf_struct_multiple_parse<T>(
>, >,
mut destructor: Option<unsafe fn(_: &T)>, mut destructor: Option<unsafe fn(_: &T)>,
) -> libc::c_int { ) -> libc::c_int {
let mut current_block: u64;
let mut struct_list = Vec::new(); let mut struct_list = Vec::new();
let mut cur_token: size_t = 0;
let mut r: libc::c_int = 0;
let mut res: libc::c_int = 0; let mut res: libc::c_int = 0;
cur_token = *indx; let mut cur_token = *indx;
match parser.expect("non-null function pointer")(message, length, &mut cur_token) { match parser.expect("non-null function pointer")(message, length, &mut cur_token) {
Err(err) => res = err, Err(r) => {
assert!(r != MAILIMF_NO_ERROR as libc::c_int);
res = r;
}
Ok(value) => { Ok(value) => {
struct_list.push(value); struct_list.push(value);
let mut has_err = false;
loop { loop {
match parser.expect("non-null function pointer")(message, length, &mut cur_token) { match parser.expect("non-null function pointer")(message, length, &mut cur_token) {
Err(r) => { Err(r) => {
assert!(r != MAILIMF_NO_ERROR as libc::c_int);
if r == MAILIMF_ERROR_PARSE as libc::c_int { if r == MAILIMF_ERROR_PARSE as libc::c_int {
current_block = 11057878835866523405;
break; break;
} }
res = r; res = r;
current_block = 8222683242185098763; has_err = true;
break; break;
} }
Ok(value) => { Ok(value) => {
@@ -4175,14 +4163,12 @@ unsafe fn mailimf_struct_multiple_parse<T>(
} }
} }
} }
match current_block {
8222683242185098763 => {} if !has_err {
_ => {
*result = struct_list; *result = struct_list;
*indx = cur_token; *indx = cur_token;
return MAILIMF_NO_ERROR as libc::c_int; return MAILIMF_NO_ERROR as libc::c_int;
} }
}
if let Some(destructor) = destructor { if let Some(destructor) = destructor {
for el in &struct_list { for el in &struct_list {
@@ -4192,8 +4178,9 @@ unsafe fn mailimf_struct_multiple_parse<T>(
} }
} }
return res; res
} }
unsafe fn mailimf_in_reply_to_parse( unsafe fn mailimf_in_reply_to_parse(
mut message: *const libc::c_char, mut message: *const libc::c_char,
mut length: size_t, mut length: size_t,
@@ -5007,7 +4994,6 @@ unsafe fn mailimf_envelope_field_parse(
let mut in_reply_to: *mut mailimf_in_reply_to = 0 as *mut mailimf_in_reply_to; let mut in_reply_to: *mut mailimf_in_reply_to = 0 as *mut mailimf_in_reply_to;
let mut references: *mut mailimf_references = 0 as *mut mailimf_references; let mut references: *mut mailimf_references = 0 as *mut mailimf_references;
let mut subject: *mut mailimf_subject = 0 as *mut mailimf_subject; let mut subject: *mut mailimf_subject = 0 as *mut mailimf_subject;
let mut optional_field: *mut mailimf_optional_field = 0 as *mut mailimf_optional_field;
let mut cur_token = *indx; let mut cur_token = *indx;
let guessed_type = guess_header_type(message, length, cur_token); let guessed_type = guess_header_type(message, length, cur_token);
@@ -5116,20 +5102,15 @@ unsafe fn mailimf_envelope_field_parse(
@return MAILIMF_NO_ERROR on success, MAILIMF_ERROR_XXX on error @return MAILIMF_NO_ERROR on success, MAILIMF_ERROR_XXX on error
*/ */
pub unsafe fn mailimf_envelope_and_optional_fields_parse( pub unsafe fn mailimf_envelope_and_optional_fields_parse(
mut message: *const libc::c_char, message: *const libc::c_char,
mut length: size_t, length: size_t,
mut indx: *mut size_t, indx: *mut size_t,
mut result: *mut *mut mailimf_fields, result: *mut *mut mailimf_fields,
) -> libc::c_int { ) -> libc::c_int {
let mut current_block: u64;
let mut cur_token: size_t = 0;
let mut list: Vec<mailimf_field> = Vec::new(); let mut list: Vec<mailimf_field> = Vec::new();
let mut fields: *mut mailimf_fields = 0 as *mut mailimf_fields; let mut cur_token = *indx;
let mut r: libc::c_int = 0;
let mut res: libc::c_int = 0;
cur_token = *indx;
r = mailimf_struct_multiple_parse( let r = mailimf_struct_multiple_parse(
message, message,
length, length,
&mut cur_token, &mut cur_token,
@@ -5137,30 +5118,20 @@ pub unsafe fn mailimf_envelope_and_optional_fields_parse(
Some(mailimf_envelope_or_optional_field_parse), Some(mailimf_envelope_or_optional_field_parse),
None, None,
); );
match r {
0 => {
/* do nothing */
current_block = 11050875288958768710;
}
1 => {
list.clear();
current_block = 11050875288958768710;
}
_ => {
res = r;
current_block = 7755940856643933760;
}
}
match current_block {
11050875288958768710 => {
*result = mailimf_fields_new(list);
*indx = cur_token;
return MAILIMF_NO_ERROR as libc::c_int;
}
_ => {}
}
res match r as libc::c_uint {
MAILIMF_NO_ERROR => {
*indx = cur_token;
*result = mailimf_fields_new(list);
MAILIMF_NO_ERROR as libc::c_int
}
MAILIMF_ERROR_PARSE => {
*indx = cur_token;
*result = mailimf_fields_new(Vec::new());
MAILIMF_NO_ERROR as libc::c_int
}
_ => r,
}
} }
unsafe fn mailimf_envelope_or_optional_field_parse( unsafe fn mailimf_envelope_or_optional_field_parse(
@@ -5170,17 +5141,19 @@ unsafe fn mailimf_envelope_or_optional_field_parse(
) -> Result<mailimf_field, libc::c_int> { ) -> Result<mailimf_field, libc::c_int> {
match mailimf_envelope_field_parse(message, length, indx) { match mailimf_envelope_field_parse(message, length, indx) {
Ok(value) => Ok(value), Ok(value) => Ok(value),
Err(_) => { Err(r) => {
let mut optional_field: *mut mailimf_optional_field = 0 as *mut mailimf_optional_field; assert!(r != MAILIMF_NO_ERROR as libc::c_int);
let mut cur_token = *indx; let mut cur_token = *indx;
let r = match mailimf_optional_field_parse(message, length, &mut cur_token) {
mailimf_optional_field_parse(message, length, &mut cur_token, &mut optional_field); Err(r) => {
if r != MAILIMF_NO_ERROR as libc::c_int { assert!(r != MAILIMF_NO_ERROR as libc::c_int);
return Err(r); Err(r)
} }
Ok(value) => {
*indx = cur_token; *indx = cur_token;
Ok(mailimf_field::OptionalField(optional_field)) Ok(mailimf_field::OptionalField(value))
}
}
} }
} }
} }
@@ -5251,16 +5224,15 @@ unsafe fn mailimf_only_optional_field_parse(
length: size_t, length: size_t,
indx: *mut size_t, indx: *mut size_t,
) -> Result<mailimf_field, libc::c_int> { ) -> Result<mailimf_field, libc::c_int> {
let mut optional_field = std::ptr::null_mut();
let mut cur_token = *indx; let mut cur_token = *indx;
let r = mailimf_optional_field_parse(message, length, &mut cur_token, &mut optional_field); match mailimf_optional_field_parse(message, length, &mut cur_token) {
if r != MAILIMF_NO_ERROR as libc::c_int { Err(r) => Err(r),
return Err(r); Ok(value) => {
}
*indx = cur_token; *indx = cur_token;
Ok(mailimf_field::OptionalField(optional_field)) Ok(mailimf_field::OptionalField(value))
}
}
} }
pub unsafe fn mailimf_custom_string_parse( pub unsafe fn mailimf_custom_string_parse(

View File

@@ -139,7 +139,15 @@ pub struct mailimf_message {
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct mailimf_fields(pub Vec<mailimf_field>); pub struct mailimf_fields(pub Vec<mailimf_field>);
#[derive(Debug, Clone)] impl Drop for mailimf_fields {
fn drop(&mut self) {
for el in &self.0 {
unsafe { mailimf_field_free(*el) };
}
}
}
#[derive(Debug, Copy, Clone)]
pub enum mailimf_field { pub enum mailimf_field {
ReturnPath(*mut mailimf_return), ReturnPath(*mut mailimf_return),
ResentDate(*mut mailimf_orig_date), ResentDate(*mut mailimf_orig_date),
@@ -174,51 +182,22 @@ impl mailimf_field {
} }
} }
impl Drop for mailimf_field { /// Non parsed optional field.
fn drop(&mut self) { #[derive(Debug, Clone)]
use mailimf_field::*;
unsafe {
match self {
ReturnPath(p) => mailimf_return_free(*p),
ResentDate(d) => mailimf_orig_date_free(*d),
ResentFrom(r) => mailimf_from_free(*r),
ResentSender(r) => mailimf_sender_free(*r),
ResentTo(r) => mailimf_to_free(*r),
ResentCc(r) => mailimf_cc_free(*r),
ResentBcc(r) => mailimf_bcc_free(*r),
ResentMsgId(r) => mailimf_message_id_free(*r),
OrigDate(d) => mailimf_orig_date_free(*d),
From(f) => mailimf_from_free(*f),
Sender(s) => mailimf_sender_free(*s),
ReplyTo(t) => mailimf_reply_to_free(*t),
To(t) => mailimf_to_free(*t),
Cc(c) => mailimf_cc_free(*c),
Bcc(c) => mailimf_bcc_free(*c),
MessageId(m) => mailimf_message_id_free(*m),
InReplyTo(i) => mailimf_in_reply_to_free(*i),
References(r) => mailimf_references_free(*r),
Subject(s) => mailimf_subject_free(*s),
Comments(c) => mailimf_comments_free(*c),
Keywords(k) => mailimf_keywords_free(*k),
OptionalField(o) => mailimf_optional_field_free(*o),
}
}
}
}
/*
mailimf_optional_field is a non-parsed field
- fld_name is the name of the field
- fld_value is the value of the field
*/
#[derive(Copy, Clone)]
#[repr(C)]
pub struct mailimf_optional_field { pub struct mailimf_optional_field {
pub fld_name: *mut libc::c_char, pub name: *mut libc::c_char,
pub fld_value: *mut libc::c_char, pub value: *mut libc::c_char,
} }
impl Drop for mailimf_optional_field {
fn drop(&mut self) {
unsafe {
mailimf_field_name_free(self.name);
mailimf_unstructured_free(self.value);
}
}
}
/* /*
mailimf_keywords is the parsed Keywords field mailimf_keywords is the parsed Keywords field
@@ -374,54 +353,52 @@ pub struct mailimf_return {
pub struct mailimf_path { pub struct mailimf_path {
pub pt_addr_spec: *mut libc::c_char, pub pt_addr_spec: *mut libc::c_char,
} }
/* other field */
pub const MAILIMF_FIELD_OPTIONAL_FIELD: unnamed_2 = 22; /// Keywords
/* Keywords */ pub(crate) const MAILIMF_FIELD_KEYWORDS: libc::c_uint = 21;
pub const MAILIMF_FIELD_KEYWORDS: unnamed_2 = 21; /// Comments
/* Comments */ pub(crate) const MAILIMF_FIELD_COMMENTS: libc::c_uint = 20;
pub const MAILIMF_FIELD_COMMENTS: unnamed_2 = 20; /// Subject
/* Subject */ pub(crate) const MAILIMF_FIELD_SUBJECT: libc::c_uint = 19;
pub const MAILIMF_FIELD_SUBJECT: unnamed_2 = 19; /// References
/* References */ pub(crate) const MAILIMF_FIELD_REFERENCES: libc::c_uint = 18;
pub const MAILIMF_FIELD_REFERENCES: unnamed_2 = 18; /// In-Reply-To
/* In-Reply-To */ pub(crate) const MAILIMF_FIELD_IN_REPLY_TO: libc::c_uint = 17;
pub const MAILIMF_FIELD_IN_REPLY_TO: unnamed_2 = 17; /// Message-ID
/* Message-ID */ pub(crate) const MAILIMF_FIELD_MESSAGE_ID: libc::c_uint = 16;
pub const MAILIMF_FIELD_MESSAGE_ID: unnamed_2 = 16; /// Bcc
/* Bcc */ pub(crate) const MAILIMF_FIELD_BCC: libc::c_uint = 15;
pub const MAILIMF_FIELD_BCC: unnamed_2 = 15; /// Cc
/* Cc */ pub(crate) const MAILIMF_FIELD_CC: libc::c_uint = 14;
pub const MAILIMF_FIELD_CC: unnamed_2 = 14; /// To
/* To */ pub(crate) const MAILIMF_FIELD_TO: libc::c_uint = 13;
pub const MAILIMF_FIELD_TO: unnamed_2 = 13; /// Reply-To
/* Reply-To */ pub(crate) const MAILIMF_FIELD_REPLY_TO: libc::c_uint = 12;
pub const MAILIMF_FIELD_REPLY_TO: unnamed_2 = 12; /// Sender
/* Sender */ pub(crate) const MAILIMF_FIELD_SENDER: libc::c_uint = 11;
pub const MAILIMF_FIELD_SENDER: unnamed_2 = 11; /// From
/* From */ pub(crate) const MAILIMF_FIELD_FROM: libc::c_uint = 10;
pub const MAILIMF_FIELD_FROM: unnamed_2 = 10; /// Date
/* Date */ pub(crate) const MAILIMF_FIELD_ORIG_DATE: libc::c_uint = 9;
pub const MAILIMF_FIELD_ORIG_DATE: unnamed_2 = 9; /// Resent-Message-ID
/* Resent-Message-ID */ pub(crate) const MAILIMF_FIELD_RESENT_MSG_ID: libc::c_uint = 8;
pub const MAILIMF_FIELD_RESENT_MSG_ID: unnamed_2 = 8; /// Resent-Bcc
/* Resent-Bcc */ pub(crate) const MAILIMF_FIELD_RESENT_BCC: libc::c_uint = 7;
pub const MAILIMF_FIELD_RESENT_BCC: unnamed_2 = 7; /// Resent-Cc
/* Resent-Cc */ pub(crate) const MAILIMF_FIELD_RESENT_CC: libc::c_uint = 6;
pub const MAILIMF_FIELD_RESENT_CC: unnamed_2 = 6; /// Resent-To
/* Resent-To */ pub(crate) const MAILIMF_FIELD_RESENT_TO: libc::c_uint = 5;
pub const MAILIMF_FIELD_RESENT_TO: unnamed_2 = 5; /// Resent-Sender
/* Resent-Sender */ pub(crate) const MAILIMF_FIELD_RESENT_SENDER: libc::c_uint = 4;
pub const MAILIMF_FIELD_RESENT_SENDER: unnamed_2 = 4; /// Resent-From
/* Resent-From */ pub(crate) const MAILIMF_FIELD_RESENT_FROM: libc::c_uint = 3;
pub const MAILIMF_FIELD_RESENT_FROM: unnamed_2 = 3; /// Resent-Date
/* Resent-Date */ pub(crate) const MAILIMF_FIELD_RESENT_DATE: libc::c_uint = 2;
pub const MAILIMF_FIELD_RESENT_DATE: unnamed_2 = 2; /// Return-Path
/* Return-Path */ pub(crate) const MAILIMF_FIELD_RETURN_PATH: libc::c_uint = 1;
pub const MAILIMF_FIELD_RETURN_PATH: unnamed_2 = 1;
/* this is a type of field */ /// on parse error
pub type unnamed_2 = libc::c_uint; pub(crate) const MAILIMF_FIELD_NONE: libc::c_uint = 0;
/* on parse error */
pub const MAILIMF_FIELD_NONE: unnamed_2 = 0;
pub unsafe fn mailimf_date_time_new( pub unsafe fn mailimf_date_time_new(
day: u32, day: u32,
@@ -626,21 +603,55 @@ pub unsafe fn mailimf_fields_free(fields: *mut mailimf_fields) {
let _ = Box::from_raw(fields); let _ = Box::from_raw(fields);
} }
#[no_mangle] pub unsafe fn mailimf_field_free(opt_field: mailimf_field) {
pub unsafe fn mailimf_optional_field_free(mut opt_field: *mut mailimf_optional_field) { use mailimf_field::*;
mailimf_field_name_free((*opt_field).fld_name); match opt_field {
mailimf_unstructured_free((*opt_field).fld_value); ReturnPath(p) => mailimf_return_free(p),
free(opt_field as *mut libc::c_void); ResentDate(d) => mailimf_orig_date_free(d),
ResentFrom(r) => mailimf_from_free(r),
ResentSender(r) => mailimf_sender_free(r),
ResentTo(r) => mailimf_to_free(r),
ResentCc(r) => mailimf_cc_free(r),
ResentBcc(r) => mailimf_bcc_free(r),
ResentMsgId(r) => mailimf_message_id_free(r),
OrigDate(d) => mailimf_orig_date_free(d),
From(f) => mailimf_from_free(f),
Sender(s) => mailimf_sender_free(s),
ReplyTo(t) => mailimf_reply_to_free(t),
To(t) => mailimf_to_free(t),
Cc(c) => mailimf_cc_free(c),
Bcc(c) => mailimf_bcc_free(c),
MessageId(m) => mailimf_message_id_free(m),
InReplyTo(i) => mailimf_in_reply_to_free(i),
References(r) => mailimf_references_free(r),
Subject(s) => mailimf_subject_free(s),
Comments(c) => mailimf_comments_free(c),
Keywords(k) => mailimf_keywords_free(k),
OptionalField(o) => mailimf_optional_field_free(o),
} }
#[no_mangle] }
pub unsafe fn mailimf_optional_field_free(opt_field: *mut mailimf_optional_field) {
if opt_field.is_null() {
return;
}
let _ = Box::from_raw(opt_field);
}
pub unsafe fn mailimf_unstructured_free(mut unstructured: *mut libc::c_char) { pub unsafe fn mailimf_unstructured_free(mut unstructured: *mut libc::c_char) {
free(unstructured as *mut libc::c_void); free(unstructured as *mut libc::c_void);
} }
#[no_mangle]
pub unsafe fn mailimf_field_name_free(mut field_name: *mut libc::c_char) { pub unsafe fn mailimf_field_name_free(field_name: *mut libc::c_char) {
if field_name.is_null() {
return;
}
let c = std::ffi::CStr::from_ptr(field_name);
free(field_name as *mut libc::c_void); free(field_name as *mut libc::c_void);
} }
#[no_mangle]
pub unsafe fn mailimf_keywords_free(mut keywords: *mut mailimf_keywords) { pub unsafe fn mailimf_keywords_free(mut keywords: *mut mailimf_keywords) {
clist_foreach( clist_foreach(
(*keywords).kw_list, (*keywords).kw_list,
@@ -908,20 +919,13 @@ pub unsafe fn mailimf_path_new(mut pt_addr_spec: *mut libc::c_char) -> *mut mail
(*path).pt_addr_spec = pt_addr_spec; (*path).pt_addr_spec = pt_addr_spec;
return path; return path;
} }
#[no_mangle]
pub unsafe fn mailimf_optional_field_new( pub unsafe fn mailimf_optional_field_new(
mut fld_name: *mut libc::c_char, name: *mut libc::c_char,
mut fld_value: *mut libc::c_char, value: *mut libc::c_char,
) -> *mut mailimf_optional_field { ) -> *mut mailimf_optional_field {
let mut opt_field: *mut mailimf_optional_field = 0 as *mut mailimf_optional_field; let f = mailimf_optional_field { name, value };
opt_field = malloc(::std::mem::size_of::<mailimf_optional_field>() as libc::size_t) Box::into_raw(Box::new(f))
as *mut mailimf_optional_field;
if opt_field.is_null() {
return 0 as *mut mailimf_optional_field;
}
(*opt_field).fld_name = fld_name;
(*opt_field).fld_value = fld_value;
opt_field
} }
/* internal use */ /* internal use */

View File

@@ -232,16 +232,10 @@ unsafe fn mailimf_optional_field_write_driver(
mut field: *mut mailimf_optional_field, mut field: *mut mailimf_optional_field,
) -> libc::c_int { ) -> libc::c_int {
let mut r: libc::c_int = 0; let mut r: libc::c_int = 0;
if strlen((*field).fld_name).wrapping_add(2i32 as libc::size_t) > 998i32 as libc::size_t { if strlen((*field).name).wrapping_add(2i32 as libc::size_t) > 998i32 as libc::size_t {
return MAILIMF_ERROR_INVAL as libc::c_int; return MAILIMF_ERROR_INVAL as libc::c_int;
} }
r = mailimf_string_write_driver( r = mailimf_string_write_driver(do_write, data, col, (*field).name, strlen((*field).name));
do_write,
data,
col,
(*field).fld_name,
strlen((*field).fld_name),
);
if r != MAILIMF_NO_ERROR as libc::c_int { if r != MAILIMF_NO_ERROR as libc::c_int {
return r; return r;
} }
@@ -259,8 +253,8 @@ unsafe fn mailimf_optional_field_write_driver(
do_write, do_write,
data, data,
col, col,
(*field).fld_value, (*field).value,
strlen((*field).fld_value), strlen((*field).value),
); );
if r != MAILIMF_NO_ERROR as libc::c_int { if r != MAILIMF_NO_ERROR as libc::c_int {
return r; return r;

View File

@@ -1251,13 +1251,13 @@ unsafe fn remove_unparsed_mime_headers(fields: *mut mailimf_fields) {
mailimf_field::OptionalField(data) => { mailimf_field::OptionalField(data) => {
delete = false; delete = false;
if strncasecmp( if strncasecmp(
(**data).fld_name, (**data).name,
b"Content-\x00" as *const u8 as *const libc::c_char, b"Content-\x00" as *const u8 as *const libc::c_char,
8i32 as libc::size_t, 8i32 as libc::size_t,
) == 0i32 ) == 0i32
{ {
let mut name: *mut libc::c_char = 0 as *mut libc::c_char; let mut name: *mut libc::c_char = 0 as *mut libc::c_char;
name = (**data).fld_name.offset(8isize); name = (**data).name.offset(8isize);
if strcasecmp(name, b"Type\x00" as *const u8 as *const libc::c_char) == 0i32 if strcasecmp(name, b"Type\x00" as *const u8 as *const libc::c_char) == 0i32
|| strcasecmp( || strcasecmp(
name, name,
@@ -1274,7 +1274,7 @@ unsafe fn remove_unparsed_mime_headers(fields: *mut mailimf_fields) {
delete = true; delete = true;
} }
} else if strcasecmp( } else if strcasecmp(
(**data).fld_name, (**data).name,
b"MIME-Version\x00" as *const u8 as *const libc::c_char, b"MIME-Version\x00" as *const u8 as *const libc::c_char,
) == 0i32 ) == 0i32
{ {

View File

@@ -684,8 +684,8 @@ unsafe fn mailmime_mechanism_parse(
} }
pub unsafe fn mailmime_field_parse( pub unsafe fn mailmime_field_parse(
mut field: *mut mailimf_optional_field, field: *mut mailimf_optional_field,
mut result: *mut *mut mailmime_field, result: *mut *mut mailmime_field,
) -> libc::c_int { ) -> libc::c_int {
let mut name: *mut libc::c_char = 0 as *mut libc::c_char; let mut name: *mut libc::c_char = 0 as *mut libc::c_char;
let mut value: *mut libc::c_char = 0 as *mut libc::c_char; let mut value: *mut libc::c_char = 0 as *mut libc::c_char;
@@ -702,8 +702,8 @@ pub unsafe fn mailmime_field_parse(
let mut location: *mut libc::c_char = 0 as *mut libc::c_char; let mut location: *mut libc::c_char = 0 as *mut libc::c_char;
let mut res: libc::c_int = 0; let mut res: libc::c_int = 0;
let mut r: libc::c_int = 0; let mut r: libc::c_int = 0;
name = (*field).fld_name; name = (*field).name;
value = (*field).fld_value; value = (*field).value;
cur_token = 0i32 as size_t; cur_token = 0i32 as size_t;
content = 0 as *mut mailmime_content; content = 0 as *mut mailmime_content;
encoding = 0 as *mut mailmime_mechanism; encoding = 0 as *mut mailmime_mechanism;

View File

@@ -705,7 +705,7 @@ pub unsafe fn mailmime_new(
} }
_ => {} _ => {}
} }
return mime; mime
} }
pub unsafe fn mailmime_new_simple( pub unsafe fn mailmime_new_simple(

View File

@@ -1,5 +1,4 @@
use std::collections::BTreeMap; use std::collections::BTreeMap;
use std::ffi::CStr;
use std::str::FromStr; use std::str::FromStr;
use std::{fmt, str}; use std::{fmt, str};
@@ -7,6 +6,7 @@ use mmime::mailimf::types::*;
use crate::constants::*; use crate::constants::*;
use crate::contact::*; use crate::contact::*;
use crate::dc_tools::as_str;
use crate::key::*; use crate::key::*;
/// Possible values for encryption preference /// Possible values for encryption preference
@@ -72,15 +72,10 @@ impl Aheader {
for field in unsafe { &(*header).0 } { for field in unsafe { &(*header).0 } {
if let mailimf_field::OptionalField(optional_field) = *field { if let mailimf_field::OptionalField(optional_field) = *field {
if !optional_field.is_null() if !optional_field.is_null()
&& unsafe { !(*optional_field).fld_name.is_null() } && unsafe { !(*optional_field).name.is_null() }
&& unsafe { CStr::from_ptr((*optional_field).fld_name).to_str().unwrap() } && unsafe { as_str((*optional_field).name) } == "Autocrypt"
== "Autocrypt"
{ {
let value = unsafe { let value = unsafe { as_str((*optional_field).value) };
CStr::from_ptr((*optional_field).fld_value)
.to_str()
.unwrap()
};
match Self::from_str(value) { match Self::from_str(value) {
Ok(test) => { Ok(test) => {

View File

@@ -340,7 +340,7 @@ impl<'a> MimeParser<'a> {
if val.is_null() { if val.is_null() {
return None; return None;
} else { } else {
return Some(unsafe { to_string_lossy((*val).fld_value) }); return Some(unsafe { to_string_lossy((*val).value) });
} }
} }
} }
@@ -923,7 +923,7 @@ unsafe fn hash_header(out: &mut HashMap<String, mailimf_field>, in_0: *const mai
// anyway we just use a lossy conversion. // anyway we just use a lossy conversion.
if !optional_field.is_null() { if !optional_field.is_null() {
Some(to_string_lossy((*optional_field).fld_name)) Some(to_string_lossy((*optional_field).name))
} else { } else {
None None
} }
@@ -934,7 +934,7 @@ unsafe fn hash_header(out: &mut HashMap<String, mailimf_field>, in_0: *const mai
if !out.contains_key(&key) || // key already exists, only overwrite known types (protected headers) if !out.contains_key(&key) || // key already exists, only overwrite known types (protected headers)
field.is_optional_field() || key.starts_with("Chat-") field.is_optional_field() || key.starts_with("Chat-")
{ {
out.insert(key, field.clone()); out.insert(key, *field);
} }
} }
} }
@@ -1288,9 +1288,9 @@ pub unsafe fn mailimf_find_optional_field(
for field in &(*header).0 { for field in &(*header).0 {
if let mailimf_field::OptionalField(optional_field) = *field { if let mailimf_field::OptionalField(optional_field) = *field {
if !optional_field.is_null() if !optional_field.is_null()
&& !(*optional_field).fld_name.is_null() && !(*optional_field).name.is_null()
&& !(*optional_field).fld_value.is_null() && !(*optional_field).value.is_null()
&& strcasecmp((*optional_field).fld_name, wanted_fld_name) == 0i32 && strcasecmp((*optional_field).name, wanted_fld_name) == 0i32
{ {
return optional_field; return optional_field;
} }
@@ -1305,7 +1305,6 @@ mod tests {
use super::*; use super::*;
use crate::test_utils::*; use crate::test_utils::*;
use proptest::prelude::*; use proptest::prelude::*;
use std::ffi::CStr;
#[test] #[test]
fn test_mailmime_parse() { fn test_mailmime_parse() {
@@ -1328,19 +1327,9 @@ mod tests {
); );
assert!(!of_a.is_null()); assert!(!of_a.is_null());
assert!(!(*of_a).fld_value.is_null()); assert!(!(*of_a).value.is_null());
assert_eq!( assert_eq!(as_str((*of_a).name), "FieldA");
CStr::from_ptr((*of_a).fld_name as *const libc::c_char) assert_eq!(as_str((*of_a).value), "ValueA");
.to_str()
.unwrap(),
"FieldA",
);
assert_eq!(
CStr::from_ptr((*of_a).fld_value as *const libc::c_char)
.to_str()
.unwrap(),
"ValueA",
);
of_a = mailimf_find_optional_field( of_a = mailimf_find_optional_field(
fields, fields,
@@ -1348,33 +1337,18 @@ mod tests {
); );
assert!(!of_a.is_null()); assert!(!of_a.is_null());
assert!(!(*of_a).fld_value.is_null()); assert!(!(*of_a).value.is_null());
assert_eq!( assert_eq!(as_str((*of_a).name), "FieldA");
CStr::from_ptr((*of_a).fld_name as *const libc::c_char) assert_eq!(as_str((*of_a).value), "ValueA");
.to_str()
.unwrap(),
"FieldA",
);
assert_eq!(
CStr::from_ptr((*of_a).fld_value as *const libc::c_char)
.to_str()
.unwrap(),
"ValueA",
);
let of_b: *mut mailimf_optional_field = mailimf_find_optional_field( let of_b = mailimf_find_optional_field(
fields, fields,
b"FieldB\x00" as *const u8 as *const libc::c_char, b"FieldB\x00" as *const u8 as *const libc::c_char,
); );
assert!(!of_b.is_null()); assert!(!of_b.is_null());
assert!(!(*of_b).fld_value.is_null()); assert!(!(*of_b).value.is_null());
assert_eq!( assert_eq!(as_str((*of_b).value), "ValueB");
CStr::from_ptr((*of_b).fld_value as *const libc::c_char)
.to_str()
.unwrap(),
"ValueB",
);
mailmime_free(mime); mailmime_free(mime);
} }

View File

@@ -824,16 +824,16 @@ unsafe fn handle_reports(
b"Original-Message-ID\x00" as *const u8 as *const libc::c_char, b"Original-Message-ID\x00" as *const u8 as *const libc::c_char,
); );
if !of_disposition.is_null() if !of_disposition.is_null()
&& !(*of_disposition).fld_value.is_null() && !(*of_disposition).value.is_null()
&& !of_org_msgid.is_null() && !of_org_msgid.is_null()
&& !(*of_org_msgid).fld_value.is_null() && !(*of_org_msgid).value.is_null()
{ {
let mut rfc724_mid_0 = std::ptr::null_mut(); let mut rfc724_mid_0 = std::ptr::null_mut();
dummy = 0; dummy = 0;
if mailimf_msg_id_parse( if mailimf_msg_id_parse(
(*of_org_msgid).fld_value, (*of_org_msgid).value,
strlen((*of_org_msgid).fld_value), strlen((*of_org_msgid).value),
&mut dummy, &mut dummy,
&mut rfc724_mid_0, &mut rfc724_mid_0,
) == MAIL_NO_ERROR as libc::c_int ) == MAIL_NO_ERROR as libc::c_int

View File

@@ -174,8 +174,8 @@ impl EncryptHelper {
move_to_encrypted = true; move_to_encrypted = true;
} }
mailimf_field::OptionalField(opt_field) => { mailimf_field::OptionalField(opt_field) => {
if !opt_field.is_null() && !(*opt_field).fld_name.is_null() { if !opt_field.is_null() && !(*opt_field).name.is_null() {
let fld_name = to_string_lossy((*opt_field).fld_name); let fld_name = to_string_lossy((*opt_field).name);
if fld_name.starts_with("Secure-Join") if fld_name.starts_with("Secure-Join")
|| (fld_name.starts_with("Chat-") && fld_name != "Chat-Version") || (fld_name.starts_with("Chat-") && fld_name != "Chat-Version")
{ {
@@ -187,7 +187,7 @@ impl EncryptHelper {
} }
if move_to_encrypted { if move_to_encrypted {
mailimf_fields_add(imffields_encrypted, field.clone()); mailimf_fields_add(imffields_encrypted, *field);
false false
} else { } else {
true true
@@ -458,11 +458,9 @@ fn update_gossip_peerstates(
continue; continue;
} }
let optional_field = unsafe { *optional_field }; let optional_field = unsafe { &*optional_field };
if !optional_field.fld_name.is_null() if !optional_field.name.is_null() && as_str(optional_field.name) == "Autocrypt-Gossip" {
&& as_str(optional_field.fld_name) == "Autocrypt-Gossip" let value = to_string_lossy(optional_field.value);
{
let value = to_string_lossy(optional_field.fld_value);
let gossip_header = Aheader::from_str(&value); let gossip_header = Aheader::from_str(&value);
if let Ok(ref header) = gossip_header { if let Ok(ref header) = gossip_header {

View File

@@ -153,7 +153,7 @@ impl<'a> MimeFactory<'a> {
/* create basic mail /* create basic mail
*************************************************************************/ *************************************************************************/
let from: *mut mailimf_mailbox_list = mailimf_mailbox_list_new_empty(); let from = mailimf_mailbox_list_new_empty();
mailimf_mailbox_list_add( mailimf_mailbox_list_add(
from, from,
mailimf_mailbox_new( mailimf_mailbox_new(
@@ -165,7 +165,7 @@ impl<'a> MimeFactory<'a> {
self.from_addr.strdup(), self.from_addr.strdup(),
), ),
); );
let mut to: *mut mailimf_address_list = ptr::null_mut(); let mut to = ptr::null_mut();
if !self.recipients_names.is_empty() && !self.recipients_addr.is_empty() { if !self.recipients_names.is_empty() && !self.recipients_addr.is_empty() {
to = mailimf_address_list_new_empty(); to = mailimf_address_list_new_empty();
let name_iter = self.recipients_names.iter(); let name_iter = self.recipients_names.iter();