mirror of
https://github.com/chatmail/core.git
synced 2026-04-19 14:36:29 +03:00
inital commit
This commit is contained in:
908
src/dc_strencode.rs
Normal file
908
src/dc_strencode.rs
Normal file
@@ -0,0 +1,908 @@
|
||||
use libc;
|
||||
|
||||
use crate::dc_tools::*;
|
||||
|
||||
extern "C" {
|
||||
#[no_mangle]
|
||||
static mut _DefaultRuneLocale: _RuneLocale;
|
||||
#[no_mangle]
|
||||
fn __maskrune(_: __darwin_ct_rune_t, _: libc::c_ulong) -> libc::c_int;
|
||||
#[no_mangle]
|
||||
fn __tolower(_: __darwin_ct_rune_t) -> __darwin_ct_rune_t;
|
||||
#[no_mangle]
|
||||
fn mmap_string_new(init: *const libc::c_char) -> *mut MMAPString;
|
||||
#[no_mangle]
|
||||
fn mmap_string_free(string: *mut MMAPString);
|
||||
#[no_mangle]
|
||||
fn mmap_string_append(string: *mut MMAPString, val: *const libc::c_char) -> *mut MMAPString;
|
||||
#[no_mangle]
|
||||
fn mmap_string_append_len(
|
||||
string: *mut MMAPString,
|
||||
val: *const libc::c_char,
|
||||
len: size_t,
|
||||
) -> *mut MMAPString;
|
||||
#[no_mangle]
|
||||
fn mmap_string_append_c(string: *mut MMAPString, c: libc::c_char) -> *mut MMAPString;
|
||||
#[no_mangle]
|
||||
fn snprintf(
|
||||
_: *mut libc::c_char,
|
||||
_: libc::c_ulong,
|
||||
_: *const libc::c_char,
|
||||
_: ...
|
||||
) -> libc::c_int;
|
||||
#[no_mangle]
|
||||
fn mailmime_encoded_phrase_parse(
|
||||
default_fromcode: *const libc::c_char,
|
||||
message: *const libc::c_char,
|
||||
length: size_t,
|
||||
indx: *mut size_t,
|
||||
tocode: *const libc::c_char,
|
||||
result: *mut *mut libc::c_char,
|
||||
) -> libc::c_int;
|
||||
#[no_mangle]
|
||||
fn charconv(
|
||||
tocode: *const libc::c_char,
|
||||
fromcode: *const libc::c_char,
|
||||
str: *const libc::c_char,
|
||||
length: size_t,
|
||||
result: *mut *mut libc::c_char,
|
||||
) -> libc::c_int;
|
||||
#[no_mangle]
|
||||
fn malloc(_: libc::c_ulong) -> *mut libc::c_void;
|
||||
#[no_mangle]
|
||||
fn free(_: *mut libc::c_void);
|
||||
#[no_mangle]
|
||||
fn exit(_: libc::c_int) -> !;
|
||||
#[no_mangle]
|
||||
fn memset(_: *mut libc::c_void, _: libc::c_int, _: libc::c_ulong) -> *mut libc::c_void;
|
||||
#[no_mangle]
|
||||
fn strchr(_: *const libc::c_char, _: libc::c_int) -> *mut libc::c_char;
|
||||
#[no_mangle]
|
||||
fn strcmp(_: *const libc::c_char, _: *const libc::c_char) -> libc::c_int;
|
||||
#[no_mangle]
|
||||
fn strcpy(_: *mut libc::c_char, _: *const libc::c_char) -> *mut libc::c_char;
|
||||
#[no_mangle]
|
||||
fn strlen(_: *const libc::c_char) -> libc::c_ulong;
|
||||
#[no_mangle]
|
||||
fn strdup(_: *const libc::c_char) -> *mut libc::c_char;
|
||||
/* string tools */
|
||||
#[no_mangle]
|
||||
fn dc_strdup(_: *const libc::c_char) -> *mut libc::c_char;
|
||||
#[no_mangle]
|
||||
fn dc_null_terminate(_: *const libc::c_char, bytes: libc::c_int) -> *mut libc::c_char;
|
||||
}
|
||||
pub type __uint32_t = libc::c_uint;
|
||||
pub type __darwin_ct_rune_t = libc::c_int;
|
||||
pub type __darwin_size_t = libc::c_ulong;
|
||||
pub type __darwin_wchar_t = libc::c_int;
|
||||
pub type __darwin_rune_t = __darwin_wchar_t;
|
||||
pub type size_t = __darwin_size_t;
|
||||
#[derive(Copy, Clone)]
|
||||
#[repr(C)]
|
||||
pub struct _RuneEntry {
|
||||
pub __min: __darwin_rune_t,
|
||||
pub __max: __darwin_rune_t,
|
||||
pub __map: __darwin_rune_t,
|
||||
pub __types: *mut __uint32_t,
|
||||
}
|
||||
#[derive(Copy, Clone)]
|
||||
#[repr(C)]
|
||||
pub struct _RuneRange {
|
||||
pub __nranges: libc::c_int,
|
||||
pub __ranges: *mut _RuneEntry,
|
||||
}
|
||||
#[derive(Copy, Clone)]
|
||||
#[repr(C)]
|
||||
pub struct _RuneCharClass {
|
||||
pub __name: [libc::c_char; 14],
|
||||
pub __mask: __uint32_t,
|
||||
}
|
||||
#[derive(Copy, Clone)]
|
||||
#[repr(C)]
|
||||
pub struct _RuneLocale {
|
||||
pub __magic: [libc::c_char; 8],
|
||||
pub __encoding: [libc::c_char; 32],
|
||||
pub __sgetrune: Option<
|
||||
unsafe extern "C" fn(
|
||||
_: *const libc::c_char,
|
||||
_: __darwin_size_t,
|
||||
_: *mut *const libc::c_char,
|
||||
) -> __darwin_rune_t,
|
||||
>,
|
||||
pub __sputrune: Option<
|
||||
unsafe extern "C" fn(
|
||||
_: __darwin_rune_t,
|
||||
_: *mut libc::c_char,
|
||||
_: __darwin_size_t,
|
||||
_: *mut *mut libc::c_char,
|
||||
) -> libc::c_int,
|
||||
>,
|
||||
pub __invalid_rune: __darwin_rune_t,
|
||||
pub __runetype: [__uint32_t; 256],
|
||||
pub __maplower: [__darwin_rune_t; 256],
|
||||
pub __mapupper: [__darwin_rune_t; 256],
|
||||
pub __runetype_ext: _RuneRange,
|
||||
pub __maplower_ext: _RuneRange,
|
||||
pub __mapupper_ext: _RuneRange,
|
||||
pub __variable: *mut libc::c_void,
|
||||
pub __variable_len: libc::c_int,
|
||||
pub __ncharclasses: libc::c_int,
|
||||
pub __charclasses: *mut _RuneCharClass,
|
||||
}
|
||||
#[derive(Copy, Clone)]
|
||||
#[repr(C)]
|
||||
pub struct _MMAPString {
|
||||
pub str_0: *mut libc::c_char,
|
||||
pub len: size_t,
|
||||
pub allocated_len: size_t,
|
||||
pub fd: libc::c_int,
|
||||
pub mmapped_size: size_t,
|
||||
}
|
||||
pub type MMAPString = _MMAPString;
|
||||
pub type unnamed = libc::c_uint;
|
||||
pub const MAILIMF_ERROR_FILE: unnamed = 4;
|
||||
pub const MAILIMF_ERROR_INVAL: unnamed = 3;
|
||||
pub const MAILIMF_ERROR_MEMORY: unnamed = 2;
|
||||
pub const MAILIMF_ERROR_PARSE: unnamed = 1;
|
||||
pub const MAILIMF_NO_ERROR: unnamed = 0;
|
||||
pub type unnamed_0 = libc::c_uint;
|
||||
pub const MAIL_CHARCONV_ERROR_CONV: unnamed_0 = 3;
|
||||
pub const MAIL_CHARCONV_ERROR_MEMORY: unnamed_0 = 2;
|
||||
pub const MAIL_CHARCONV_ERROR_UNKNOWN_CHARSET: unnamed_0 = 1;
|
||||
pub const MAIL_CHARCONV_NO_ERROR: unnamed_0 = 0;
|
||||
#[inline]
|
||||
unsafe extern "C" fn isascii(mut _c: libc::c_int) -> libc::c_int {
|
||||
return (_c & !0x7fi32 == 0i32) as libc::c_int;
|
||||
}
|
||||
#[inline]
|
||||
unsafe extern "C" fn __istype(mut _c: __darwin_ct_rune_t, mut _f: libc::c_ulong) -> libc::c_int {
|
||||
return if 0 != isascii(_c) {
|
||||
(0 != _DefaultRuneLocale.__runetype[_c as usize] as libc::c_ulong & _f) as libc::c_int
|
||||
} else {
|
||||
(0 != __maskrune(_c, _f)) as libc::c_int
|
||||
};
|
||||
}
|
||||
#[inline]
|
||||
unsafe extern "C" fn __isctype(
|
||||
mut _c: __darwin_ct_rune_t,
|
||||
mut _f: libc::c_ulong,
|
||||
) -> __darwin_ct_rune_t {
|
||||
return if _c < 0i32 || _c >= 1i32 << 8i32 {
|
||||
0i32
|
||||
} else {
|
||||
(0 != _DefaultRuneLocale.__runetype[_c as usize] as libc::c_ulong & _f) as libc::c_int
|
||||
};
|
||||
}
|
||||
#[no_mangle]
|
||||
#[inline]
|
||||
pub unsafe extern "C" fn isalnum(mut _c: libc::c_int) -> libc::c_int {
|
||||
return __istype(_c, (0x100i64 | 0x400i64) as libc::c_ulong);
|
||||
}
|
||||
#[no_mangle]
|
||||
#[inline]
|
||||
pub unsafe extern "C" fn isdigit(mut _c: libc::c_int) -> libc::c_int {
|
||||
return __isctype(_c, 0x400i64 as libc::c_ulong);
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn dc_urlencode(mut to_encode: *const libc::c_char) -> *mut libc::c_char {
|
||||
let mut pstr: *const libc::c_char = to_encode;
|
||||
if to_encode.is_null() {
|
||||
return dc_strdup(b"\x00" as *const u8 as *const libc::c_char);
|
||||
}
|
||||
let mut buf: *mut libc::c_char = malloc(
|
||||
strlen(to_encode)
|
||||
.wrapping_mul(3i32 as libc::c_ulong)
|
||||
.wrapping_add(1i32 as libc::c_ulong),
|
||||
) as *mut libc::c_char;
|
||||
let mut pbuf: *mut libc::c_char = buf;
|
||||
if buf.is_null() {
|
||||
exit(46i32);
|
||||
}
|
||||
while 0 != *pstr {
|
||||
if 0 != isalnum(*pstr as libc::c_int)
|
||||
|| *pstr as libc::c_int == '-' as i32
|
||||
|| *pstr as libc::c_int == '_' as i32
|
||||
|| *pstr as libc::c_int == '.' as i32
|
||||
|| *pstr as libc::c_int == '~' as i32
|
||||
{
|
||||
let fresh0 = pbuf;
|
||||
pbuf = pbuf.offset(1);
|
||||
*fresh0 = *pstr
|
||||
} else if *pstr as libc::c_int == ' ' as i32 {
|
||||
let fresh1 = pbuf;
|
||||
pbuf = pbuf.offset(1);
|
||||
*fresh1 = '+' as i32 as libc::c_char
|
||||
} else {
|
||||
let fresh2 = pbuf;
|
||||
pbuf = pbuf.offset(1);
|
||||
*fresh2 = '%' as i32 as libc::c_char;
|
||||
let fresh3 = pbuf;
|
||||
pbuf = pbuf.offset(1);
|
||||
*fresh3 = int_2_uppercase_hex((*pstr as libc::c_int >> 4i32) as libc::c_char);
|
||||
let fresh4 = pbuf;
|
||||
pbuf = pbuf.offset(1);
|
||||
*fresh4 = int_2_uppercase_hex((*pstr as libc::c_int & 15i32) as libc::c_char)
|
||||
}
|
||||
pstr = pstr.offset(1isize)
|
||||
}
|
||||
*pbuf = '\u{0}' as i32 as libc::c_char;
|
||||
return buf;
|
||||
}
|
||||
/* ******************************************************************************
|
||||
* URL encoding and decoding, RFC 3986
|
||||
******************************************************************************/
|
||||
unsafe extern "C" fn int_2_uppercase_hex(mut code: libc::c_char) -> libc::c_char {
|
||||
static mut hex: [libc::c_char; 17] = [
|
||||
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 68, 69, 70, 0,
|
||||
];
|
||||
return hex[(code as libc::c_int & 15i32) as usize];
|
||||
}
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn dc_urldecode(mut to_decode: *const libc::c_char) -> *mut libc::c_char {
|
||||
let mut pstr: *const libc::c_char = to_decode;
|
||||
if to_decode.is_null() {
|
||||
return dc_strdup(b"\x00" as *const u8 as *const libc::c_char);
|
||||
}
|
||||
let mut buf: *mut libc::c_char =
|
||||
malloc(strlen(to_decode).wrapping_add(1i32 as libc::c_ulong)) as *mut libc::c_char;
|
||||
let mut pbuf: *mut libc::c_char = buf;
|
||||
if buf.is_null() {
|
||||
exit(50i32);
|
||||
}
|
||||
while 0 != *pstr {
|
||||
if *pstr as libc::c_int == '%' as i32 {
|
||||
if 0 != *pstr.offset(1isize) as libc::c_int && 0 != *pstr.offset(2isize) as libc::c_int
|
||||
{
|
||||
let fresh5 = pbuf;
|
||||
pbuf = pbuf.offset(1);
|
||||
*fresh5 = ((hex_2_int(*pstr.offset(1isize)) as libc::c_int) << 4i32
|
||||
| hex_2_int(*pstr.offset(2isize)) as libc::c_int)
|
||||
as libc::c_char;
|
||||
pstr = pstr.offset(2isize)
|
||||
}
|
||||
} else if *pstr as libc::c_int == '+' as i32 {
|
||||
let fresh6 = pbuf;
|
||||
pbuf = pbuf.offset(1);
|
||||
*fresh6 = ' ' as i32 as libc::c_char
|
||||
} else {
|
||||
let fresh7 = pbuf;
|
||||
pbuf = pbuf.offset(1);
|
||||
*fresh7 = *pstr
|
||||
}
|
||||
pstr = pstr.offset(1isize)
|
||||
}
|
||||
*pbuf = '\u{0}' as i32 as libc::c_char;
|
||||
return buf;
|
||||
}
|
||||
unsafe extern "C" fn hex_2_int(mut ch: libc::c_char) -> libc::c_char {
|
||||
return (if 0 != isdigit(ch as libc::c_int) {
|
||||
ch as libc::c_int - '0' as i32
|
||||
} else {
|
||||
tolower(ch as libc::c_int) - 'a' as i32 + 10i32
|
||||
}) as libc::c_char;
|
||||
}
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn dc_encode_header_words(
|
||||
mut to_encode: *const libc::c_char,
|
||||
) -> *mut libc::c_char {
|
||||
let mut current_block: u64;
|
||||
let mut ret_str: *mut libc::c_char = 0 as *mut libc::c_char;
|
||||
let mut cur: *const libc::c_char = to_encode;
|
||||
let mut mmapstr: *mut MMAPString = mmap_string_new(b"\x00" as *const u8 as *const libc::c_char);
|
||||
if to_encode.is_null() || mmapstr.is_null() {
|
||||
current_block = 8550051112593613029;
|
||||
} else {
|
||||
current_block = 4644295000439058019;
|
||||
}
|
||||
loop {
|
||||
match current_block {
|
||||
8550051112593613029 => {
|
||||
if !mmapstr.is_null() {
|
||||
mmap_string_free(mmapstr);
|
||||
}
|
||||
break;
|
||||
}
|
||||
_ => {
|
||||
if *cur as libc::c_int != '\u{0}' as i32 {
|
||||
let mut begin: *const libc::c_char = 0 as *const libc::c_char;
|
||||
let mut end: *const libc::c_char = 0 as *const libc::c_char;
|
||||
let mut do_quote: libc::c_int = 0;
|
||||
let mut quote_words: libc::c_int = 0;
|
||||
begin = cur;
|
||||
end = begin;
|
||||
quote_words = 0i32;
|
||||
do_quote = 1i32;
|
||||
while *cur as libc::c_int != '\u{0}' as i32 {
|
||||
get_word(cur, &mut cur, &mut do_quote);
|
||||
if !(0 != do_quote) {
|
||||
break;
|
||||
}
|
||||
quote_words = 1i32;
|
||||
end = cur;
|
||||
if *cur as libc::c_int != '\u{0}' as i32 {
|
||||
cur = cur.offset(1isize)
|
||||
}
|
||||
}
|
||||
if 0 != quote_words {
|
||||
if 0 == quote_word(
|
||||
b"utf-8\x00" as *const u8 as *const libc::c_char,
|
||||
mmapstr,
|
||||
begin,
|
||||
end.wrapping_offset_from(begin) as libc::c_long as size_t,
|
||||
) {
|
||||
current_block = 8550051112593613029;
|
||||
continue;
|
||||
}
|
||||
if *end as libc::c_int == ' ' as i32 || *end as libc::c_int == '\t' as i32 {
|
||||
if mmap_string_append_c(mmapstr, *end).is_null() {
|
||||
current_block = 8550051112593613029;
|
||||
continue;
|
||||
}
|
||||
end = end.offset(1isize)
|
||||
}
|
||||
if *end as libc::c_int != '\u{0}' as i32 {
|
||||
if mmap_string_append_len(
|
||||
mmapstr,
|
||||
end,
|
||||
cur.wrapping_offset_from(end) as libc::c_long as size_t,
|
||||
)
|
||||
.is_null()
|
||||
{
|
||||
current_block = 8550051112593613029;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
} else if mmap_string_append_len(
|
||||
mmapstr,
|
||||
begin,
|
||||
cur.wrapping_offset_from(begin) as libc::c_long as size_t,
|
||||
)
|
||||
.is_null()
|
||||
{
|
||||
current_block = 8550051112593613029;
|
||||
continue;
|
||||
}
|
||||
if !(*cur as libc::c_int == ' ' as i32 || *cur as libc::c_int == '\t' as i32) {
|
||||
current_block = 4644295000439058019;
|
||||
continue;
|
||||
}
|
||||
if mmap_string_append_c(mmapstr, *cur).is_null() {
|
||||
current_block = 8550051112593613029;
|
||||
continue;
|
||||
}
|
||||
cur = cur.offset(1isize);
|
||||
current_block = 4644295000439058019;
|
||||
} else {
|
||||
ret_str = strdup((*mmapstr).str_0);
|
||||
current_block = 8550051112593613029;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret_str;
|
||||
}
|
||||
unsafe extern "C" fn quote_word(
|
||||
mut display_charset: *const libc::c_char,
|
||||
mut mmapstr: *mut MMAPString,
|
||||
mut word: *const libc::c_char,
|
||||
mut size: size_t,
|
||||
) -> libc::c_int {
|
||||
let mut cur: *const libc::c_char = 0 as *const libc::c_char;
|
||||
let mut i: size_t = 0i32 as size_t;
|
||||
let mut hex: [libc::c_char; 4] = [0; 4];
|
||||
let mut col: libc::c_int = 0i32;
|
||||
if mmap_string_append(mmapstr, b"=?\x00" as *const u8 as *const libc::c_char).is_null() {
|
||||
return 0i32;
|
||||
}
|
||||
if mmap_string_append(mmapstr, display_charset).is_null() {
|
||||
return 0i32;
|
||||
}
|
||||
if mmap_string_append(mmapstr, b"?Q?\x00" as *const u8 as *const libc::c_char).is_null() {
|
||||
return 0i32;
|
||||
}
|
||||
col = (*mmapstr).len as libc::c_int;
|
||||
cur = word;
|
||||
i = 0i32 as size_t;
|
||||
while i < size {
|
||||
let mut do_quote_char: libc::c_int = 0;
|
||||
do_quote_char = 0i32;
|
||||
match *cur as libc::c_int {
|
||||
44 | 58 | 33 | 34 | 35 | 36 | 64 | 91 | 92 | 93 | 94 | 96 | 123 | 124 | 125 | 126
|
||||
| 61 | 63 | 95 => do_quote_char = 1i32,
|
||||
_ => {
|
||||
if *cur as libc::c_uchar as libc::c_int >= 128i32 {
|
||||
do_quote_char = 1i32
|
||||
}
|
||||
}
|
||||
}
|
||||
if 0 != do_quote_char {
|
||||
snprintf(
|
||||
hex.as_mut_ptr(),
|
||||
4i32 as libc::c_ulong,
|
||||
b"=%2.2X\x00" as *const u8 as *const libc::c_char,
|
||||
*cur as libc::c_uchar as libc::c_int,
|
||||
);
|
||||
if mmap_string_append(mmapstr, hex.as_mut_ptr()).is_null() {
|
||||
return 0i32;
|
||||
}
|
||||
col += 3i32
|
||||
} else {
|
||||
if *cur as libc::c_int == ' ' as i32 {
|
||||
if mmap_string_append_c(mmapstr, '_' as i32 as libc::c_char).is_null() {
|
||||
return 0i32;
|
||||
}
|
||||
} else if mmap_string_append_c(mmapstr, *cur).is_null() {
|
||||
return 0i32;
|
||||
}
|
||||
col += 3i32
|
||||
}
|
||||
cur = cur.offset(1isize);
|
||||
i = i.wrapping_add(1)
|
||||
}
|
||||
if mmap_string_append(mmapstr, b"?=\x00" as *const u8 as *const libc::c_char).is_null() {
|
||||
return 0i32;
|
||||
}
|
||||
return 1i32;
|
||||
}
|
||||
unsafe extern "C" fn get_word(
|
||||
mut begin: *const libc::c_char,
|
||||
mut pend: *mut *const libc::c_char,
|
||||
mut pto_be_quoted: *mut libc::c_int,
|
||||
) {
|
||||
let mut cur: *const libc::c_char = begin;
|
||||
while *cur as libc::c_int != ' ' as i32
|
||||
&& *cur as libc::c_int != '\t' as i32
|
||||
&& *cur as libc::c_int != '\u{0}' as i32
|
||||
{
|
||||
cur = cur.offset(1isize)
|
||||
}
|
||||
*pto_be_quoted = to_be_quoted(
|
||||
begin,
|
||||
cur.wrapping_offset_from(begin) as libc::c_long as size_t,
|
||||
);
|
||||
*pend = cur;
|
||||
}
|
||||
/* ******************************************************************************
|
||||
* Encode/decode header words, RFC 2047
|
||||
******************************************************************************/
|
||||
/* see comment below */
|
||||
unsafe extern "C" fn to_be_quoted(mut word: *const libc::c_char, mut size: size_t) -> libc::c_int {
|
||||
let mut cur: *const libc::c_char = word;
|
||||
let mut i: size_t = 0i32 as size_t;
|
||||
i = 0i32 as size_t;
|
||||
while i < size {
|
||||
match *cur as libc::c_int {
|
||||
44 | 58 | 33 | 34 | 35 | 36 | 64 | 91 | 92 | 93 | 94 | 96 | 123 | 124 | 125 | 126
|
||||
| 61 | 63 | 95 => return 1i32,
|
||||
_ => {
|
||||
if *cur as libc::c_uchar as libc::c_int >= 128i32 {
|
||||
return 1i32;
|
||||
}
|
||||
}
|
||||
}
|
||||
cur = cur.offset(1isize);
|
||||
i = i.wrapping_add(1)
|
||||
}
|
||||
return 0i32;
|
||||
}
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn dc_decode_header_words(
|
||||
mut in_0: *const libc::c_char,
|
||||
) -> *mut libc::c_char {
|
||||
if in_0.is_null() {
|
||||
return 0 as *mut libc::c_char;
|
||||
}
|
||||
let mut out: *mut libc::c_char = 0 as *mut libc::c_char;
|
||||
let mut cur_token: size_t = 0i32 as size_t;
|
||||
let mut r: libc::c_int = mailmime_encoded_phrase_parse(
|
||||
b"iso-8859-1\x00" as *const u8 as *const libc::c_char,
|
||||
in_0,
|
||||
strlen(in_0),
|
||||
&mut cur_token,
|
||||
b"utf-8\x00" as *const u8 as *const libc::c_char,
|
||||
&mut out,
|
||||
);
|
||||
if r != MAILIMF_NO_ERROR as libc::c_int || out.is_null() {
|
||||
out = dc_strdup(in_0)
|
||||
}
|
||||
return out;
|
||||
}
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn dc_encode_modified_utf7(
|
||||
mut to_encode: *const libc::c_char,
|
||||
mut change_spaces: libc::c_int,
|
||||
) -> *mut libc::c_char {
|
||||
let mut utf8pos: libc::c_uint = 0i32 as libc::c_uint;
|
||||
let mut utf8total: libc::c_uint = 0i32 as libc::c_uint;
|
||||
let mut c: libc::c_uint = 0i32 as libc::c_uint;
|
||||
let mut utf7mode: libc::c_uint = 0i32 as libc::c_uint;
|
||||
let mut bitstogo: libc::c_uint = 0i32 as libc::c_uint;
|
||||
let mut utf16flag: libc::c_uint = 0i32 as libc::c_uint;
|
||||
let mut ucs4: libc::c_ulong = 0i32 as libc::c_ulong;
|
||||
let mut bitbuf: libc::c_ulong = 0i32 as libc::c_ulong;
|
||||
let mut dst: *mut libc::c_char = 0 as *mut libc::c_char;
|
||||
let mut res: *mut libc::c_char = 0 as *mut libc::c_char;
|
||||
if to_encode.is_null() {
|
||||
return dc_strdup(b"\x00" as *const u8 as *const libc::c_char);
|
||||
}
|
||||
res = malloc(
|
||||
(2i32 as libc::c_ulong)
|
||||
.wrapping_mul(strlen(to_encode))
|
||||
.wrapping_add(1i32 as libc::c_ulong),
|
||||
) as *mut libc::c_char;
|
||||
dst = res;
|
||||
if dst.is_null() {
|
||||
exit(51i32);
|
||||
}
|
||||
utf7mode = 0i32 as libc::c_uint;
|
||||
utf8total = 0i32 as libc::c_uint;
|
||||
bitstogo = 0i32 as libc::c_uint;
|
||||
utf8pos = 0i32 as libc::c_uint;
|
||||
loop {
|
||||
c = *to_encode as libc::c_uchar as libc::c_uint;
|
||||
if !(c != '\u{0}' as i32 as libc::c_uint) {
|
||||
break;
|
||||
}
|
||||
to_encode = to_encode.offset(1isize);
|
||||
// normal character?
|
||||
if c >= ' ' as i32 as libc::c_uint
|
||||
&& c <= '~' as i32 as libc::c_uint
|
||||
&& (c != '_' as i32 as libc::c_uint || 0 == change_spaces)
|
||||
{
|
||||
if 0 != utf7mode {
|
||||
if 0 != bitstogo {
|
||||
let fresh8 = dst;
|
||||
dst = dst.offset(1);
|
||||
*fresh8 = base64chars[(bitbuf << (6i32 as libc::c_uint).wrapping_sub(bitstogo)
|
||||
& 0x3fi32 as libc::c_ulong)
|
||||
as usize]
|
||||
}
|
||||
let fresh9 = dst;
|
||||
dst = dst.offset(1);
|
||||
*fresh9 = '-' as i32 as libc::c_char;
|
||||
utf7mode = 0i32 as libc::c_uint;
|
||||
utf8pos = 0i32 as libc::c_uint;
|
||||
bitstogo = 0i32 as libc::c_uint;
|
||||
utf8total = 0i32 as libc::c_uint
|
||||
}
|
||||
if 0 != change_spaces && c == ' ' as i32 as libc::c_uint {
|
||||
let fresh10 = dst;
|
||||
dst = dst.offset(1);
|
||||
*fresh10 = '_' as i32 as libc::c_char
|
||||
} else {
|
||||
let fresh11 = dst;
|
||||
dst = dst.offset(1);
|
||||
*fresh11 = c as libc::c_char
|
||||
}
|
||||
if c == '&' as i32 as libc::c_uint {
|
||||
let fresh12 = dst;
|
||||
dst = dst.offset(1);
|
||||
*fresh12 = '-' as i32 as libc::c_char
|
||||
}
|
||||
} else {
|
||||
if 0 == utf7mode {
|
||||
let fresh13 = dst;
|
||||
dst = dst.offset(1);
|
||||
*fresh13 = '&' as i32 as libc::c_char;
|
||||
utf7mode = 1i32 as libc::c_uint
|
||||
}
|
||||
// encode ascii characters as themselves
|
||||
if c < 0x80i32 as libc::c_uint {
|
||||
ucs4 = c as libc::c_ulong
|
||||
} else if 0 != utf8total {
|
||||
ucs4 = ucs4 << 6i32 | c as libc::c_ulong & 0x3fu64;
|
||||
utf8pos = utf8pos.wrapping_add(1);
|
||||
if utf8pos < utf8total {
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
utf8pos = 1i32 as libc::c_uint;
|
||||
if c < 0xe0i32 as libc::c_uint {
|
||||
utf8total = 2i32 as libc::c_uint;
|
||||
ucs4 = (c & 0x1fi32 as libc::c_uint) as libc::c_ulong
|
||||
} else if c < 0xf0i32 as libc::c_uint {
|
||||
utf8total = 3i32 as libc::c_uint;
|
||||
ucs4 = (c & 0xfi32 as libc::c_uint) as libc::c_ulong
|
||||
} else {
|
||||
utf8total = 4i32 as libc::c_uint;
|
||||
ucs4 = (c & 0x3i32 as libc::c_uint) as libc::c_ulong
|
||||
}
|
||||
continue;
|
||||
}
|
||||
utf8total = 0i32 as libc::c_uint;
|
||||
loop {
|
||||
if ucs4 >= 0x10000u64 {
|
||||
ucs4 = ucs4.wrapping_sub(0x10000u64);
|
||||
bitbuf = bitbuf << 16i32 | (ucs4 >> 10i32).wrapping_add(0xd800u64);
|
||||
ucs4 = (ucs4 & 0x3ffu64).wrapping_add(0xdc00u64);
|
||||
utf16flag = 1i32 as libc::c_uint
|
||||
} else {
|
||||
bitbuf = bitbuf << 16i32 | ucs4;
|
||||
utf16flag = 0i32 as libc::c_uint
|
||||
}
|
||||
bitstogo = bitstogo.wrapping_add(16i32 as libc::c_uint);
|
||||
while bitstogo >= 6i32 as libc::c_uint {
|
||||
bitstogo = bitstogo.wrapping_sub(6i32 as libc::c_uint);
|
||||
let fresh14 = dst;
|
||||
dst = dst.offset(1);
|
||||
*fresh14 = base64chars[(if 0 != bitstogo {
|
||||
bitbuf >> bitstogo
|
||||
} else {
|
||||
bitbuf
|
||||
} & 0x3fi32 as libc::c_ulong)
|
||||
as usize]
|
||||
}
|
||||
if !(0 != utf16flag) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if 0 != utf7mode {
|
||||
if 0 != bitstogo {
|
||||
let fresh15 = dst;
|
||||
dst = dst.offset(1);
|
||||
*fresh15 = base64chars[(bitbuf << (6i32 as libc::c_uint).wrapping_sub(bitstogo)
|
||||
& 0x3fi32 as libc::c_ulong) as usize]
|
||||
}
|
||||
let fresh16 = dst;
|
||||
dst = dst.offset(1);
|
||||
*fresh16 = '-' as i32 as libc::c_char
|
||||
}
|
||||
*dst = '\u{0}' as i32 as libc::c_char;
|
||||
return res;
|
||||
}
|
||||
/* ******************************************************************************
|
||||
* Encode/decode modified UTF-7 as needed for IMAP, see RFC 2192
|
||||
******************************************************************************/
|
||||
// UTF7 modified base64 alphabet
|
||||
static mut base64chars: [libc::c_char; 65] = [
|
||||
65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88,
|
||||
89, 90, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114,
|
||||
115, 116, 117, 118, 119, 120, 121, 122, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 43, 44, 0,
|
||||
];
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn dc_decode_modified_utf7(
|
||||
mut to_decode: *const libc::c_char,
|
||||
mut change_spaces: libc::c_int,
|
||||
) -> *mut libc::c_char {
|
||||
let mut c: libc::c_uint = 0i32 as libc::c_uint;
|
||||
let mut i: libc::c_uint = 0i32 as libc::c_uint;
|
||||
let mut bitcount: libc::c_uint = 0i32 as libc::c_uint;
|
||||
let mut ucs4: libc::c_ulong = 0i32 as libc::c_ulong;
|
||||
let mut utf16: libc::c_ulong = 0i32 as libc::c_ulong;
|
||||
let mut bitbuf: libc::c_ulong = 0i32 as libc::c_ulong;
|
||||
let mut base64: [libc::c_uchar; 256] = [0; 256];
|
||||
let mut src: *const libc::c_char = 0 as *const libc::c_char;
|
||||
let mut dst: *mut libc::c_char = 0 as *mut libc::c_char;
|
||||
let mut res: *mut libc::c_char = 0 as *mut libc::c_char;
|
||||
if to_decode.is_null() {
|
||||
return dc_strdup(b"\x00" as *const u8 as *const libc::c_char);
|
||||
}
|
||||
res = malloc(
|
||||
(4i32 as libc::c_ulong)
|
||||
.wrapping_mul(strlen(to_decode))
|
||||
.wrapping_add(1i32 as libc::c_ulong),
|
||||
) as *mut libc::c_char;
|
||||
dst = res;
|
||||
src = to_decode;
|
||||
if dst.is_null() {
|
||||
exit(52i32);
|
||||
}
|
||||
memset(
|
||||
base64.as_mut_ptr() as *mut libc::c_void,
|
||||
64i32,
|
||||
::std::mem::size_of::<[libc::c_uchar; 256]>() as libc::c_ulong,
|
||||
);
|
||||
i = 0i32 as libc::c_uint;
|
||||
while (i as libc::c_ulong) < ::std::mem::size_of::<[libc::c_char; 65]>() as libc::c_ulong {
|
||||
base64[base64chars[i as usize] as libc::c_uint as usize] = i as libc::c_uchar;
|
||||
i = i.wrapping_add(1)
|
||||
}
|
||||
while *src as libc::c_int != '\u{0}' as i32 {
|
||||
let fresh17 = src;
|
||||
src = src.offset(1);
|
||||
c = *fresh17 as libc::c_uint;
|
||||
if c != '&' as i32 as libc::c_uint || *src as libc::c_int == '-' as i32 {
|
||||
if 0 != change_spaces && c == '_' as i32 as libc::c_uint {
|
||||
let fresh18 = dst;
|
||||
dst = dst.offset(1);
|
||||
*fresh18 = ' ' as i32 as libc::c_char
|
||||
} else {
|
||||
let fresh19 = dst;
|
||||
dst = dst.offset(1);
|
||||
*fresh19 = c as libc::c_char
|
||||
}
|
||||
if c == '&' as i32 as libc::c_uint {
|
||||
src = src.offset(1isize)
|
||||
}
|
||||
} else {
|
||||
bitbuf = 0i32 as libc::c_ulong;
|
||||
bitcount = 0i32 as libc::c_uint;
|
||||
ucs4 = 0i32 as libc::c_ulong;
|
||||
loop {
|
||||
c = base64[*src as libc::c_uchar as usize] as libc::c_uint;
|
||||
if !(c != 64i32 as libc::c_uint) {
|
||||
break;
|
||||
}
|
||||
src = src.offset(1isize);
|
||||
bitbuf = bitbuf << 6i32 | c as libc::c_ulong;
|
||||
bitcount = bitcount.wrapping_add(6i32 as libc::c_uint);
|
||||
// enough bits for a UTF-16 character?
|
||||
if !(bitcount >= 16i32 as libc::c_uint) {
|
||||
continue;
|
||||
}
|
||||
bitcount = bitcount.wrapping_sub(16i32 as libc::c_uint);
|
||||
utf16 = if 0 != bitcount {
|
||||
bitbuf >> bitcount
|
||||
} else {
|
||||
bitbuf
|
||||
} & 0xffffi32 as libc::c_ulong;
|
||||
// convert UTF16 to UCS4
|
||||
if utf16 >= 0xd800u64 && utf16 <= 0xdbffu64 {
|
||||
ucs4 = utf16.wrapping_sub(0xd800u64) << 10i32
|
||||
} else {
|
||||
if utf16 >= 0xdc00u64 && utf16 <= 0xdfffu64 {
|
||||
ucs4 = ucs4
|
||||
.wrapping_add(utf16.wrapping_sub(0xdc00u64).wrapping_add(0x10000u64))
|
||||
} else {
|
||||
ucs4 = utf16
|
||||
}
|
||||
if ucs4 <= 0x7fu64 {
|
||||
*dst.offset(0isize) = ucs4 as libc::c_char;
|
||||
dst = dst.offset(1isize)
|
||||
} else if ucs4 <= 0x7ffu64 {
|
||||
*dst.offset(0isize) =
|
||||
(0xc0i32 as libc::c_ulong | ucs4 >> 6i32) as libc::c_char;
|
||||
*dst.offset(1isize) = (0x80i32 as libc::c_ulong
|
||||
| ucs4 & 0x3fi32 as libc::c_ulong)
|
||||
as libc::c_char;
|
||||
dst = dst.offset(2isize)
|
||||
} else if ucs4 <= 0xffffu64 {
|
||||
*dst.offset(0isize) =
|
||||
(0xe0i32 as libc::c_ulong | ucs4 >> 12i32) as libc::c_char;
|
||||
*dst.offset(1isize) = (0x80i32 as libc::c_ulong
|
||||
| ucs4 >> 6i32 & 0x3fi32 as libc::c_ulong)
|
||||
as libc::c_char;
|
||||
*dst.offset(2isize) = (0x80i32 as libc::c_ulong
|
||||
| ucs4 & 0x3fi32 as libc::c_ulong)
|
||||
as libc::c_char;
|
||||
dst = dst.offset(3isize)
|
||||
} else {
|
||||
*dst.offset(0isize) =
|
||||
(0xf0i32 as libc::c_ulong | ucs4 >> 18i32) as libc::c_char;
|
||||
*dst.offset(1isize) = (0x80i32 as libc::c_ulong
|
||||
| ucs4 >> 12i32 & 0x3fi32 as libc::c_ulong)
|
||||
as libc::c_char;
|
||||
*dst.offset(2isize) = (0x80i32 as libc::c_ulong
|
||||
| ucs4 >> 6i32 & 0x3fi32 as libc::c_ulong)
|
||||
as libc::c_char;
|
||||
*dst.offset(3isize) = (0x80i32 as libc::c_ulong
|
||||
| ucs4 & 0x3fi32 as libc::c_ulong)
|
||||
as libc::c_char;
|
||||
dst = dst.offset(4isize)
|
||||
}
|
||||
}
|
||||
}
|
||||
if *src as libc::c_int == '-' as i32 {
|
||||
src = src.offset(1isize)
|
||||
}
|
||||
}
|
||||
}
|
||||
*dst = '\u{0}' as i32 as libc::c_char;
|
||||
return res;
|
||||
}
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn dc_needs_ext_header(mut to_check: *const libc::c_char) -> libc::c_int {
|
||||
if !to_check.is_null() {
|
||||
while 0 != *to_check {
|
||||
if 0 == isalnum(*to_check as libc::c_int)
|
||||
&& *to_check as libc::c_int != '-' as i32
|
||||
&& *to_check as libc::c_int != '_' as i32
|
||||
&& *to_check as libc::c_int != '.' as i32
|
||||
&& *to_check as libc::c_int != '~' as i32
|
||||
{
|
||||
return 1i32;
|
||||
}
|
||||
to_check = to_check.offset(1isize)
|
||||
}
|
||||
}
|
||||
return 0i32;
|
||||
}
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn dc_encode_ext_header(
|
||||
mut to_encode: *const libc::c_char,
|
||||
) -> *mut libc::c_char {
|
||||
let mut pstr: *const libc::c_char = to_encode;
|
||||
if to_encode.is_null() {
|
||||
return dc_strdup(b"utf-8\'\'\x00" as *const u8 as *const libc::c_char);
|
||||
}
|
||||
let mut buf: *mut libc::c_char = malloc(
|
||||
strlen(b"utf-8\'\'\x00" as *const u8 as *const libc::c_char)
|
||||
.wrapping_add(strlen(to_encode).wrapping_mul(3i32 as libc::c_ulong))
|
||||
.wrapping_add(1i32 as libc::c_ulong),
|
||||
) as *mut libc::c_char;
|
||||
if buf.is_null() {
|
||||
exit(46i32);
|
||||
}
|
||||
let mut pbuf: *mut libc::c_char = buf;
|
||||
strcpy(pbuf, b"utf-8\'\'\x00" as *const u8 as *const libc::c_char);
|
||||
pbuf = pbuf.offset(strlen(pbuf) as isize);
|
||||
while 0 != *pstr {
|
||||
if 0 != isalnum(*pstr as libc::c_int)
|
||||
|| *pstr as libc::c_int == '-' as i32
|
||||
|| *pstr as libc::c_int == '_' as i32
|
||||
|| *pstr as libc::c_int == '.' as i32
|
||||
|| *pstr as libc::c_int == '~' as i32
|
||||
{
|
||||
let fresh20 = pbuf;
|
||||
pbuf = pbuf.offset(1);
|
||||
*fresh20 = *pstr
|
||||
} else {
|
||||
let fresh21 = pbuf;
|
||||
pbuf = pbuf.offset(1);
|
||||
*fresh21 = '%' as i32 as libc::c_char;
|
||||
let fresh22 = pbuf;
|
||||
pbuf = pbuf.offset(1);
|
||||
*fresh22 = int_2_uppercase_hex((*pstr as libc::c_int >> 4i32) as libc::c_char);
|
||||
let fresh23 = pbuf;
|
||||
pbuf = pbuf.offset(1);
|
||||
*fresh23 = int_2_uppercase_hex((*pstr as libc::c_int & 15i32) as libc::c_char)
|
||||
}
|
||||
pstr = pstr.offset(1isize)
|
||||
}
|
||||
*pbuf = '\u{0}' as i32 as libc::c_char;
|
||||
return buf;
|
||||
}
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn dc_decode_ext_header(
|
||||
mut to_decode: *const libc::c_char,
|
||||
) -> *mut libc::c_char {
|
||||
let mut decoded: *mut libc::c_char = 0 as *mut libc::c_char;
|
||||
let mut charset: *mut libc::c_char = 0 as *mut libc::c_char;
|
||||
let mut p2: *const libc::c_char = 0 as *const libc::c_char;
|
||||
if !to_decode.is_null() {
|
||||
// get char set
|
||||
p2 = strchr(to_decode, '\'' as i32);
|
||||
if !(p2.is_null() || p2 == to_decode) {
|
||||
/*no empty charset allowed*/
|
||||
charset = dc_null_terminate(
|
||||
to_decode,
|
||||
p2.wrapping_offset_from(to_decode) as libc::c_long as libc::c_int,
|
||||
);
|
||||
p2 = p2.offset(1isize);
|
||||
// skip language
|
||||
p2 = strchr(p2, '\'' as i32);
|
||||
if !p2.is_null() {
|
||||
p2 = p2.offset(1isize);
|
||||
decoded = dc_urldecode(p2);
|
||||
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
|
||||
{
|
||||
let mut converted: *mut libc::c_char = 0 as *mut libc::c_char;
|
||||
let mut r: libc::c_int = charconv(
|
||||
b"utf-8\x00" as *const u8 as *const libc::c_char,
|
||||
charset,
|
||||
decoded,
|
||||
strlen(decoded),
|
||||
&mut converted,
|
||||
);
|
||||
if r == MAIL_CHARCONV_NO_ERROR as libc::c_int && !converted.is_null() {
|
||||
free(decoded as *mut libc::c_void);
|
||||
decoded = converted
|
||||
} else {
|
||||
free(converted as *mut libc::c_void);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
free(charset as *mut libc::c_void);
|
||||
return if !decoded.is_null() {
|
||||
decoded
|
||||
} else {
|
||||
dc_strdup(to_decode)
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user