diff --git a/examples/repl/main.rs b/examples/repl/main.rs index 465a05c3d..41fc28126 100644 --- a/examples/repl/main.rs +++ b/examples/repl/main.rs @@ -320,10 +320,8 @@ unsafe fn main_0(argc: libc::c_int, argv: *mut *mut libc::c_char) -> libc::c_int || strcmp(cmd, b"getbadqr\x00" as *const u8 as *const libc::c_char) == 0i32 { handles = Some(start_threads(ctx.clone())); - let qrstr: *mut libc::c_char = dc_get_securejoin_qr( - &ctx.read().unwrap(), - (if !arg1.is_null() { atoi(arg1) } else { 0i32 }) as uint32_t, - ); + let qrstr: *mut libc::c_char = + dc_get_securejoin_qr(&ctx.read().unwrap(), dc_atoi_null_is_0(arg1) as u32); if !qrstr.is_null() && 0 != *qrstr.offset(0isize) as libc::c_int { if strcmp(cmd, b"getbadqr\x00" as *const u8 as *const libc::c_char) == 0i32 && strlen(qrstr) > 40 diff --git a/src/dc_array.rs b/src/dc_array.rs index d50a54813..95c7bf0ad 100644 --- a/src/dc_array.rs +++ b/src/dc_array.rs @@ -62,9 +62,7 @@ pub unsafe fn dc_array_add_uint(mut array: *mut dc_array_t, item: uintptr_t) { (*array).array as *mut libc::c_void, (newsize).wrapping_mul(::std::mem::size_of::()), ) as *mut uintptr_t; - if (*array).array.is_null() { - exit(49i32); - } + assert!(!(*array).array.is_null()); (*array).allocated = newsize as size_t } *(*array).array.offset((*array).count as isize) = item; @@ -266,9 +264,8 @@ pub unsafe fn dc_array_new(initsize: size_t) -> *mut dc_array_t { pub unsafe fn dc_array_new_typed(type_0: libc::c_int, initsize: size_t) -> *mut dc_array_t { let mut array: *mut dc_array_t; array = calloc(1, ::std::mem::size_of::()) as *mut dc_array_t; - if array.is_null() { - exit(47i32); - } + assert!(!array.is_null()); + (*array).magic = 0xa11aai32 as uint32_t; (*array).count = 0i32 as size_t; (*array).allocated = if initsize < 1 { 1 } else { initsize }; diff --git a/src/dc_chatlist.rs b/src/dc_chatlist.rs index 0332bb9e7..420e00b54 100644 --- a/src/dc_chatlist.rs +++ b/src/dc_chatlist.rs @@ -83,15 +83,12 @@ pub unsafe fn dc_get_chatlist<'a>( pub unsafe fn dc_chatlist_new(context: &Context) -> *mut dc_chatlist_t { let mut chatlist: *mut dc_chatlist_t; chatlist = calloc(1, ::std::mem::size_of::()) as *mut dc_chatlist_t; - if chatlist.is_null() { - exit(20i32); - } + assert!(!chatlist.is_null()); + (*chatlist).magic = 0xc4a71157u32; (*chatlist).context = context; (*chatlist).chatNlastmsg_ids = dc_array_new(128i32 as size_t); - if (*chatlist).chatNlastmsg_ids.is_null() { - exit(32i32); - } + assert!(!(*chatlist).chatNlastmsg_ids.is_null()); chatlist } diff --git a/src/dc_configure.rs b/src/dc_configure.rs index c59c5e2bd..374e39a09 100644 --- a/src/dc_configure.rs +++ b/src/dc_configure.rs @@ -1406,7 +1406,7 @@ unsafe fn moz_autoconfigure_text_cb( (*(*moz_ac).out).mail_server = val; val = 0 as *mut libc::c_char } - 11 => (*(*moz_ac).out).mail_port = atoi(val), + 11 => (*(*moz_ac).out).mail_port = dc_atoi_null_is_0(val), 12 => { free((*(*moz_ac).out).mail_user as *mut libc::c_void); (*(*moz_ac).out).mail_user = val; @@ -1432,7 +1432,7 @@ unsafe fn moz_autoconfigure_text_cb( (*(*moz_ac).out).send_server = val; val = 0 as *mut libc::c_char } - 11 => (*(*moz_ac).out).send_port = atoi(val), + 11 => (*(*moz_ac).out).send_port = to_str(val).parse().unwrap_or_default(), 12 => { free((*(*moz_ac).out).send_user as *mut libc::c_void); (*(*moz_ac).out).send_user = val; diff --git a/src/dc_contact.rs b/src/dc_contact.rs index b4a69e528..ed7355abf 100644 --- a/src/dc_contact.rs +++ b/src/dc_contact.rs @@ -240,9 +240,8 @@ pub unsafe fn dc_block_contact(context: &Context, contact_id: uint32_t, new_bloc pub unsafe fn dc_contact_new<'a>(context: &'a Context) -> *mut dc_contact_t<'a> { let mut contact: *mut dc_contact_t; contact = calloc(1, ::std::mem::size_of::()) as *mut dc_contact_t; - if contact.is_null() { - exit(19i32); - } + assert!(!contact.is_null()); + (*contact).magic = 0xc047ac7i32 as uint32_t; (*contact).context = context; diff --git a/src/dc_loginparam.rs b/src/dc_loginparam.rs index 3475f2499..3f18a23ec 100644 --- a/src/dc_loginparam.rs +++ b/src/dc_loginparam.rs @@ -23,9 +23,7 @@ pub struct dc_loginparam_t { pub unsafe fn dc_loginparam_new() -> *mut dc_loginparam_t { let loginparam: *mut dc_loginparam_t; loginparam = calloc(1, ::std::mem::size_of::()) as *mut dc_loginparam_t; - if loginparam.is_null() { - exit(22i32); - } + assert!(!loginparam.is_null()); loginparam } diff --git a/src/dc_lot.rs b/src/dc_lot.rs index c913258e1..2903a385c 100644 --- a/src/dc_lot.rs +++ b/src/dc_lot.rs @@ -36,9 +36,8 @@ pub struct dc_lot_t { pub unsafe fn dc_lot_new() -> *mut dc_lot_t { let mut lot: *mut dc_lot_t; lot = calloc(1, ::std::mem::size_of::()) as *mut dc_lot_t; - if lot.is_null() { - exit(27i32); - } + assert!(!lot.is_null()); + (*lot).magic = 0x107107i32 as uint32_t; (*lot).text1_meaning = 0i32; diff --git a/src/dc_mimeparser.rs b/src/dc_mimeparser.rs index a21bca76a..59e05a3d0 100644 --- a/src/dc_mimeparser.rs +++ b/src/dc_mimeparser.rs @@ -360,7 +360,7 @@ pub unsafe fn dc_mimeparser_parse( b"Chat-Duration\x00" as *const u8 as *const libc::c_char, ); if !field_0.is_null() { - let duration_ms: libc::c_int = atoi((*field_0).fld_value); + let duration_ms: libc::c_int = dc_atoi_null_is_0((*field_0).fld_value); if duration_ms > 0i32 && duration_ms < 24i32 * 60i32 * 60i32 * 1000i32 { dc_param_set_int((*part_3).param, 'd' as i32, duration_ms); } @@ -439,9 +439,7 @@ pub unsafe fn dc_mimeparser_parse( unsafe fn dc_mimepart_new() -> *mut dc_mimepart_t { let mut mimepart: *mut dc_mimepart_t; mimepart = calloc(1, ::std::mem::size_of::()) as *mut dc_mimepart_t; - if mimepart.is_null() { - exit(33i32); - } + assert!(!mimepart.is_null()); (*mimepart).type_0 = 0i32; (*mimepart).param = dc_param_new(); mimepart diff --git a/src/dc_msg.rs b/src/dc_msg.rs index da0a071cf..f8f45d427 100644 --- a/src/dc_msg.rs +++ b/src/dc_msg.rs @@ -302,9 +302,7 @@ pub unsafe fn dc_msg_new_untyped<'a>(context: &'a Context) -> *mut dc_msg_t<'a> pub unsafe fn dc_msg_new<'a>(context: &'a Context, viewtype: libc::c_int) -> *mut dc_msg_t<'a> { let mut msg: *mut dc_msg_t; msg = calloc(1, ::std::mem::size_of::()) as *mut dc_msg_t; - if msg.is_null() { - exit(15i32); - } + assert!(!msg.is_null()); (*msg).context = context; (*msg).magic = 0x11561156i32 as uint32_t; (*msg).type_0 = viewtype; diff --git a/src/dc_param.rs b/src/dc_param.rs index cb6aa5a5a..7b2821397 100644 --- a/src/dc_param.rs +++ b/src/dc_param.rs @@ -164,7 +164,7 @@ pub unsafe fn dc_param_get_int( if str.is_null() { return def; } - let ret: int32_t = atol(str) as int32_t; + let ret: int32_t = to_str(str).parse().unwrap_or_default(); free(str as *mut libc::c_void); ret @@ -300,9 +300,7 @@ pub unsafe fn dc_param_set_int(param: *mut dc_param_t, key: libc::c_int, value: pub unsafe fn dc_param_new() -> *mut dc_param_t { let mut param: *mut dc_param_t; param = calloc(1, ::std::mem::size_of::()) as *mut dc_param_t; - if param.is_null() { - exit(28i32); - } + assert!(!param.is_null()); (*param).packed = calloc(1, 1) as *mut libc::c_char; param diff --git a/src/dc_simplify.rs b/src/dc_simplify.rs index 9d70afe84..9ecc2329e 100644 --- a/src/dc_simplify.rs +++ b/src/dc_simplify.rs @@ -15,9 +15,7 @@ pub struct dc_simplify_t { pub unsafe fn dc_simplify_new() -> *mut dc_simplify_t { let simplify: *mut dc_simplify_t; simplify = calloc(1, ::std::mem::size_of::()) as *mut dc_simplify_t; - if simplify.is_null() { - exit(31i32); - } + assert!(!simplify.is_null()); simplify } diff --git a/src/dc_sqlite3.rs b/src/dc_sqlite3.rs index f4df6b12c..0b1b27d9e 100644 --- a/src/dc_sqlite3.rs +++ b/src/dc_sqlite3.rs @@ -1166,7 +1166,7 @@ pub unsafe fn dc_sqlite3_get_config_int( if str.is_null() { return def; } - let ret = atoi(str) as int32_t; + let ret = dc_atoi_null_is_0(str); free(str as *mut libc::c_void); ret } diff --git a/src/dc_strbuilder.rs b/src/dc_strbuilder.rs index a5a460393..9881cd371 100644 --- a/src/dc_strbuilder.rs +++ b/src/dc_strbuilder.rs @@ -19,9 +19,7 @@ pub unsafe fn dc_strbuilder_init(mut strbuilder: *mut dc_strbuilder_t, init_byte 128i32 }; (*strbuilder).buf = malloc((*strbuilder).allocated as usize) as *mut libc::c_char; - if (*strbuilder).buf.is_null() { - exit(38i32); - } + assert!(!(*strbuilder).buf.is_null()); *(*strbuilder).buf.offset(0isize) = 0i32 as libc::c_char; (*strbuilder).free = (*strbuilder).allocated - 1i32; (*strbuilder).eos = (*strbuilder).buf; @@ -47,9 +45,7 @@ pub unsafe fn dc_strbuilder_cat( (*strbuilder).buf as *mut libc::c_void, ((*strbuilder).allocated + add_bytes) as usize, ) as *mut libc::c_char; - if (*strbuilder).buf.is_null() { - exit(39i32); - } + assert!(!(*strbuilder).buf.is_null()); (*strbuilder).free = (*strbuilder).free + add_bytes; (*strbuilder).eos = (*strbuilder).buf.offset(old_offset as isize) } diff --git a/src/dc_strencode.rs b/src/dc_strencode.rs index 66f3ffb9f..bf9b962ef 100644 --- a/src/dc_strencode.rs +++ b/src/dc_strencode.rs @@ -10,18 +10,9 @@ use crate::types::*; use crate::x::*; #[inline] -pub fn isalnum(mut _c: libc::c_int) -> libc::c_int { - if _c < std::u8::MAX as libc::c_int { - (_c as u8 as char).is_ascii_alphanumeric() as libc::c_int - } else { - 0 - } -} - -#[inline] -pub fn isdigit(mut _c: libc::c_int) -> libc::c_int { - if _c < std::u8::MAX as libc::c_int { - (_c as u8 as char).is_ascii_digit() as libc::c_int +pub fn isalnum(c: libc::c_int) -> libc::c_int { + if c < std::u8::MAX as libc::c_int { + (c as u8 as char).is_ascii_alphanumeric() as libc::c_int } else { 0 } @@ -116,12 +107,16 @@ pub unsafe fn dc_urldecode(to_decode: *const libc::c_char) -> *mut libc::c_char buf } -unsafe fn hex_2_int(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; +fn hex_2_int(ch: libc::c_char) -> libc::c_char { + let ch = ch as u8 as char; + if !ch.is_ascii_hexdigit() { + return (ch.to_ascii_lowercase() as i32 - 'a' as i32 + 10) as libc::c_char; + } + + match ch.to_digit(16) { + Some(res) => res as libc::c_char, + None => 0, + } } pub unsafe fn dc_encode_header_words(to_encode: *const libc::c_char) -> *mut libc::c_char { @@ -956,4 +951,11 @@ mod tests { free(buf2 as *mut libc::c_void); } } + #[test] + fn test_hex_to_int() { + assert_eq!(hex_2_int(b'A' as libc::c_char), 10); + assert_eq!(hex_2_int(b'a' as libc::c_char), 10); + assert_eq!(hex_2_int(b'4' as libc::c_char), 4); + assert_eq!(hex_2_int(b'K' as libc::c_char), 20); + } } diff --git a/src/dc_tools.rs b/src/dc_tools.rs index 9acf9e8b7..7ed8a0f3d 100644 --- a/src/dc_tools.rs +++ b/src/dc_tools.rs @@ -27,14 +27,10 @@ pub unsafe fn dc_strdup(s: *const libc::c_char) -> *mut libc::c_char { let ret: *mut libc::c_char; if !s.is_null() { ret = strdup(s); - if ret.is_null() { - exit(16i32); - } + assert!(!ret.is_null()); } else { ret = calloc(1, 1) as *mut libc::c_char; - if ret.is_null() { - exit(17i32); - } + assert!(!ret.is_null()); } ret @@ -50,24 +46,19 @@ pub unsafe fn dc_strdup_keep_null(s: *const libc::c_char) -> *mut libc::c_char { } pub unsafe fn dc_atoi_null_is_0(s: *const libc::c_char) -> libc::c_int { - return if !s.is_null() { atoi(s) } else { 0i32 }; + if !s.is_null() { + to_str(s).parse().unwrap_or_default() + } else { + 0 + } } -pub unsafe fn dc_atof(str: *const libc::c_char) -> libc::c_double { - // hack around atof() that may accept only `,` as decimal point on mac - let test: *mut libc::c_char = dc_mprintf(b"%f\x00" as *const u8 as *const libc::c_char, 1.2f64); - *test.offset(2isize) = 0i32 as libc::c_char; - let mut str_locale: *mut libc::c_char = dc_strdup(str); - dc_str_replace( - &mut str_locale, - b".\x00" as *const u8 as *const libc::c_char, - test.offset(1isize), - ); - let f: libc::c_double = atof(str_locale); - free(test as *mut libc::c_void); - free(str_locale as *mut libc::c_void); +pub fn dc_atof(s: *const libc::c_char) -> libc::c_double { + if s.is_null() { + return 0.; + } - f + to_str(s).parse().unwrap_or_default() } pub unsafe fn dc_str_replace( @@ -184,22 +175,14 @@ pub unsafe fn dc_trim(buf: *mut libc::c_char) { /* the result must be free()'d */ pub unsafe fn dc_strlower(in_0: *const libc::c_char) -> *mut libc::c_char { - let out: *mut libc::c_char = dc_strdup(in_0); - let mut p: *mut libc::c_char = out; - while 0 != *p { - *p = tolower(*p as libc::c_int) as libc::c_char; - p = p.offset(1isize) - } - - out + let raw = to_cstring(to_string(in_0).to_lowercase()); + strdup(raw.as_ptr()) } pub unsafe fn dc_strlower_in_place(in_0: *mut libc::c_char) { - let mut p: *mut libc::c_char = in_0; - while 0 != *p { - *p = tolower(*p as libc::c_int) as libc::c_char; - p = p.offset(1isize) - } + let raw = to_cstring(to_string(in_0).to_lowercase()); + assert_eq!(strlen(in_0), strlen(raw.as_ptr())); + memcpy(in_0 as *mut _, raw.as_ptr() as *const _, strlen(in_0)); } pub unsafe fn dc_str_contains( @@ -231,9 +214,7 @@ pub unsafe fn dc_null_terminate( bytes: libc::c_int, ) -> *mut libc::c_char { let out: *mut libc::c_char = malloc(bytes as usize + 1) as *mut libc::c_char; - if out.is_null() { - exit(45i32); - } + assert!(!out.is_null()); if !in_0.is_null() && bytes > 0i32 { strncpy(out, in_0, bytes as usize); } @@ -566,9 +547,8 @@ pub unsafe fn dc_str_to_clist( delimiter: *const libc::c_char, ) -> *mut clist { let list: *mut clist = clist_new(); - if list.is_null() { - exit(54i32); - } + assert!(!list.is_null()); + if !str.is_null() && !delimiter.is_null() && strlen(delimiter) >= 1 { let mut p1: *const libc::c_char = str; loop { @@ -779,9 +759,8 @@ unsafe fn encode_66bits_as_base64(v1: uint32_t, v2: uint32_t, fill: uint32_t) -> hex: 64 bit, 4 bits/character, length = 64/4 = 16 characters base64: 64 bit, 6 bits/character, length = 64/6 = 11 characters (plus 2 additional bits) */ let ret: *mut libc::c_char = malloc(12) as *mut libc::c_char; - if ret.is_null() { - exit(34i32); - } + assert!(!ret.is_null()); + static mut chars: [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, @@ -1554,11 +1533,9 @@ mod tests { #[test] fn test_dc_atof() { - unsafe { - let f: libc::c_double = dc_atof(b"1.23\x00" as *const u8 as *const libc::c_char); - assert!(f > 1.22f64); - assert!(f < 1.24f64); - } + let f: libc::c_double = dc_atof(b"1.23\x00" as *const u8 as *const libc::c_char); + assert!(f > 1.22f64); + assert!(f < 1.24f64); } #[test] diff --git a/src/types.rs b/src/types.rs index 9619dc8ea..364e60c85 100644 --- a/src/types.rs +++ b/src/types.rs @@ -5,32 +5,14 @@ pub use libsqlite3_sys::*; pub use mmime::carray::*; pub use mmime::clist::*; -pub type __builtin_va_list = [__va_list_tag; 1]; -#[derive(Copy, Clone)] -#[repr(C)] -pub struct __va_list_tag { - pub gp_offset: libc::c_uint, - pub fp_offset: libc::c_uint, - pub overflow_arg_area: *mut libc::c_void, - pub reg_save_area: *mut libc::c_void, -} -pub type va_list = __builtin_va_list; -pub type __int64_t = libc::c_longlong; -pub type __darwin_ct_rune_t = libc::c_int; -pub type __darwin_wchar_t = libc::c_int; -pub type __darwin_rune_t = __darwin_wchar_t; -pub type uint64_t = libc::c_ulonglong; - -/** - * Callback function that should be given to dc_context_new(). - * - * @memberof Context - * @param context The context object as returned by dc_context_new(). - * @param event one of the @ref DC_EVENT constants - * @param data1 depends on the event parameter - * @param data2 depends on the event parameter - * @return return 0 unless stated otherwise in the event parameter documentation - */ +/// Callback function that should be given to dc_context_new(). +/// +/// @memberof Context +/// @param context The context object as returned by dc_context_new(). +/// @param event one of the @ref DC_EVENT constants +/// @param data1 depends on the event parameter +/// @param data2 depends on the event parameter +/// @return return 0 unless stated otherwise in the event parameter documentation pub type dc_callback_t = unsafe extern "C" fn(_: &Context, _: Event, _: uintptr_t, _: uintptr_t) -> uintptr_t; @@ -62,15 +44,9 @@ pub type sqlite3_int64 = sqlite_int64; pub type int32_t = libc::int32_t; pub type int64_t = libc::int64_t; pub type uintptr_t = libc::uintptr_t; -pub type __uint8_t = libc::uint8_t; -pub type __uint16_t = libc::uint16_t; -pub type __int32_t = libc::int32_t; -pub type __uint64_t = libc::uint64_t; - pub type size_t = libc::size_t; pub type ssize_t = libc::ssize_t; pub type uint32_t = libc::c_uint; pub type uint8_t = libc::c_uchar; pub type uint16_t = libc::c_ushort; - -pub type __uint32_t = libc::c_uint; +pub type uint64_t = libc::uint64_t; diff --git a/src/x.rs b/src/x.rs index 4c3a5f816..bacb5d900 100644 --- a/src/x.rs +++ b/src/x.rs @@ -3,9 +3,8 @@ use crate::dc_tools::*; use crate::types::*; pub use libc::{ - atoi, calloc, exit, free, malloc, memcmp, memcpy, memmove, memset, realloc, strcat, strchr, - strcmp, strcpy, strcspn, strlen, strncmp, strncpy, strrchr, strspn, strstr, strtol, system, - tolower, write, + calloc, exit, free, malloc, memcmp, memcpy, memmove, memset, realloc, strcat, strchr, strcmp, + strcpy, strcspn, strlen, strncmp, strncpy, strrchr, strspn, strstr, strtol, system, }; pub unsafe fn strdup(s: *const libc::c_char) -> *mut libc::c_char { @@ -43,7 +42,6 @@ extern "C" { unsafe extern "C" fn(_: *const libc::c_void, _: *const libc::c_void) -> libc::c_int, >, ); - pub fn atol(_: *const libc::c_char) -> libc::c_long; pub fn vsnprintf( _: *mut libc::c_char, _: libc::c_ulong, @@ -57,14 +55,6 @@ extern "C" { pub fn dc_mprintf(format: *const libc::c_char, _: ...) -> *mut libc::c_char; } -#[cfg(not(target_os = "android"))] -pub use libc::atof; - -#[cfg(target_os = "android")] -pub unsafe fn atof(nptr: *mut libc::c_char) -> libc::c_double { - libc::strtod(nptr, std::ptr::null_mut()) -} - pub(crate) unsafe fn strcasecmp(s1: *const libc::c_char, s2: *const libc::c_char) -> libc::c_int { let s1 = std::ffi::CStr::from_ptr(s1) .to_string_lossy() @@ -105,14 +95,6 @@ mod tests { use super::*; use crate::dc_tools::to_string; - #[test] - fn test_atox() { - unsafe { - assert_eq!(atol(b"\x00" as *const u8 as *const libc::c_char), 0); - assert_eq!(atoi(b"\x00" as *const u8 as *const libc::c_char), 0); - } - } - #[test] fn test_strndup() { unsafe {