diff --git a/src/dc_array.rs b/src/dc_array.rs index 3ef41e7a0..16fc163ab 100644 --- a/src/dc_array.rs +++ b/src/dc_array.rs @@ -358,65 +358,46 @@ pub unsafe fn dc_array_get_string( array: *const dc_array_t, sep: *const libc::c_char, ) -> *mut libc::c_char { - let ret: *mut libc::c_char; if array.is_null() || (*array).magic != 0xa11aai32 as libc::c_uint || sep.is_null() { return dc_strdup(b"\x00" as *const u8 as *const libc::c_char); } - let mut i = 0; - ret = malloc( - (*array) - .count - .wrapping_mul((11usize).wrapping_add(strlen(sep))) - .wrapping_add(1), - ) as *mut libc::c_char; - if ret.is_null() { - exit(35i32); - } - *ret.offset(0isize) = 0i32 as libc::c_char; - while i < (*array).count { - if 0 != i { - strcat(ret, sep); - } - sprintf( - &mut *ret.offset(strlen(ret) as isize) as *mut libc::c_char, - b"%lu\x00" as *const u8 as *const libc::c_char, - *(*array).array.offset(i as isize) as libc::c_ulong, - ); - i += 1 - } + let cnt = (*array).count as usize; + let slice = std::slice::from_raw_parts((*array).array, cnt); + let sep = to_str(sep); - ret + let res = slice + .iter() + .enumerate() + .fold(String::with_capacity(2 * cnt), |mut res, (i, n)| { + if i == 0 { + res += &n.to_string(); + } else { + res += sep; + res += &n.to_string(); + } + res + }); + strdup(to_cstring(res).as_ptr()) } +/// return comma-separated value-string from integer array pub unsafe fn dc_arr_to_string(arr: *const uint32_t, cnt: libc::c_int) -> *mut libc::c_char { - /* return comma-separated value-string from integer array */ - let ret: *mut libc::c_char; - let sep: *const libc::c_char = b",\x00" as *const u8 as *const libc::c_char; - if arr.is_null() || cnt <= 0i32 { + if arr.is_null() || cnt == 0 { return dc_strdup(b"\x00" as *const u8 as *const libc::c_char); } - let mut i: libc::c_int; - ret = malloc( - (cnt as usize) - .wrapping_mul((11usize).wrapping_add(strlen(sep))) - .wrapping_add(0usize), - ) as *mut libc::c_char; - if ret.is_null() { - exit(35i32); - } - *ret.offset(0isize) = 0i32 as libc::c_char; - i = 0i32; - while i < cnt { - if 0 != i { - strcat(ret, sep); - } - sprintf( - &mut *ret.offset(strlen(ret) as isize) as *mut libc::c_char, - b"%lu\x00" as *const u8 as *const libc::c_char, - *arr.offset(i as isize) as libc::c_ulong, - ); - i += 1 - } - ret + let slice = std::slice::from_raw_parts(arr, cnt as usize); + let res = slice.iter().enumerate().fold( + String::with_capacity(2 * cnt as usize), + |mut res, (i, n)| { + if i == 0 { + res += &n.to_string(); + } else { + res += ","; + res += &n.to_string(); + } + res + }, + ); + strdup(to_cstring(res).as_ptr()) } diff --git a/src/dc_receive_imf.rs b/src/dc_receive_imf.rs index 24fefd7c3..de4670e36 100644 --- a/src/dc_receive_imf.rs +++ b/src/dc_receive_imf.rs @@ -5,6 +5,7 @@ use mmime::mailmime_content::*; use mmime::mailmime_types::*; use mmime::mmapstring::*; use mmime::other::*; +use sha2::{Digest, Sha256}; use crate::constants::*; use crate::context::Context; @@ -25,7 +26,6 @@ use crate::dc_strbuilder::*; use crate::dc_strencode::*; use crate::dc_tools::*; use crate::peerstate::*; -use crate::pgp::dc_hash_sha256; use crate::types::*; use crate::x::*; @@ -1694,7 +1694,6 @@ unsafe fn create_adhoc_grp_id(context: &Context, member_ids: *mut dc_array_t) -> let mut addr: *mut libc::c_char; let mut i: libc::c_int; let iCnt: libc::c_int; - let mut ret: *mut libc::c_char = 0 as *mut libc::c_char; let mut member_cs: dc_strbuilder_t = dc_strbuilder_t { buf: 0 as *mut libc::c_char, allocated: 0, @@ -1734,34 +1733,31 @@ unsafe fn create_adhoc_grp_id(context: &Context, member_ids: *mut dc_array_t) -> ); i += 1 } - /* make sha-256 from the string */ - let (binary_hash, binary_hash_len) = dc_hash_sha256( - member_cs.buf as *const uint8_t, - strlen(member_cs.buf) as usize, - ); - if !binary_hash.is_null() { - ret = calloc(1, 256) as *mut libc::c_char; - if !ret.is_null() { - i = 0; - while i < 8 { - sprintf( - &mut *ret.offset((i * 2i32) as isize) as *mut libc::c_char, - b"%02x\x00" as *const u8 as *const libc::c_char, - *binary_hash.offset(i as isize) as libc::c_int, - ); - i += 1 - } - let _v = Vec::from_raw_parts(binary_hash, binary_hash_len, binary_hash_len); - } - } + + let ret = hex_hash(member_cs.buf as *const _, strlen(member_cs.buf)); dc_array_free_ptr(member_addrs); dc_array_unref(member_addrs); free(member_ids_str as *mut libc::c_void); sqlite3_finalize(stmt); sqlite3_free(q3 as *mut libc::c_void); free(member_cs.buf as *mut libc::c_void); - return ret; + + ret as *mut _ } + +fn hex_hash(bytes_ptr: *const u8, bytes_len: libc::size_t) -> *const libc::c_char { + if bytes_ptr.is_null() || bytes_len == 0 { + return std::ptr::null(); + } + + let bytes = unsafe { std::slice::from_raw_parts(bytes_ptr, bytes_len) }; + let result = Sha256::digest(bytes); + let result_hex = hex::encode(&result[..8]); + let result_cstring = to_cstring(result_hex); + + unsafe { strdup(result_cstring.as_ptr()) } +} + unsafe fn search_chat_ids_by_contact_ids( context: &Context, unsorted_contact_ids: *const dc_array_t, @@ -2299,3 +2295,17 @@ unsafe fn add_or_lookup_contact_by_addr( } }; } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_hex_hash() { + let data = b"hello world\x00" as *const u8 as *const libc::c_char; + + let res_c = hex_hash(data as *const _, unsafe { strlen(data) }); + let res = to_string(res_c); + assert_eq!(res, "b94d27b9934d3e08"); + } +} diff --git a/src/pgp.rs b/src/pgp.rs index 423ac0f3d..e66f0197a 100644 --- a/src/pgp.rs +++ b/src/pgp.rs @@ -10,7 +10,6 @@ use pgp::composed::{ use pgp::crypto::{HashAlgorithm, SymmetricKeyAlgorithm}; use pgp::types::{CompressionAlgorithm, KeyTrait, SecretKeyTrait, StringToKey}; use rand::thread_rng; -use sha2::{Digest, Sha256}; use crate::dc_tools::*; use crate::key::*; @@ -329,21 +328,3 @@ pub fn dc_pgp_symm_decrypt( .ok() .and_then(|content| content) } - -/// Calculate the SHA256 hash of the given bytes. -pub fn dc_hash_sha256(bytes_ptr: *const u8, bytes_len: libc::size_t) -> (*mut u8, libc::size_t) { - assert!(!bytes_ptr.is_null()); - assert!(bytes_len > 0); - - let bytes = unsafe { std::slice::from_raw_parts(bytes_ptr, bytes_len) }; - let result = Sha256::digest(bytes); - - let mut r = result.to_vec(); - r.shrink_to_fit(); - - let ptr = r.as_ptr(); - let len = r.len(); - std::mem::forget(r); - - (ptr as *mut _, len) -} diff --git a/src/x.rs b/src/x.rs index ebaa91913..51cff4ddc 100644 --- a/src/x.rs +++ b/src/x.rs @@ -4,8 +4,8 @@ use crate::types::*; pub use libc::{ atoi, calloc, close, closedir, exit, fclose, fgets, fopen, fread, free, fseek, ftell, fwrite, malloc, memcmp, memcpy, memmove, memset, mkdir, open, opendir, printf, read, readdir, realloc, - remove, sprintf, strcat, strchr, strcmp, strcpy, strcspn, strlen, strncmp, strncpy, strrchr, - strspn, strstr, strtol, system, tolower, write, + remove, strcat, strchr, strcmp, strcpy, strcspn, strlen, strncmp, strncpy, strrchr, strspn, + strstr, strtol, system, tolower, write, }; pub unsafe fn strdup(s: *const libc::c_char) -> *mut libc::c_char { diff --git a/tests/stress.rs b/tests/stress.rs index 8ab4f463f..213ea2156 100644 --- a/tests/stress.rs +++ b/tests/stress.rs @@ -810,8 +810,7 @@ unsafe fn stress_functions(context: &Context) { as *const u8 as *const libc::c_char); } else { }; - let mut str_0: *mut libc::c_char = - dc_array_get_string(arr, b"-\x00" as *const u8 as *const libc::c_char); + let str_0 = dc_array_get_string(arr, b"-\x00" as *const u8 as *const libc::c_char); if 0 != !(strcmp( str_0, b"0-7-13-666-5000\x00" as *const u8 as *const libc::c_char, @@ -827,28 +826,6 @@ unsafe fn stress_functions(context: &Context) { } else { }; free(str_0 as *mut libc::c_void); - let arr2: [uint32_t; 4] = [ - 0i32 as uint32_t, - 12i32 as uint32_t, - 133i32 as uint32_t, - 1999999i32 as uint32_t, - ]; - str_0 = dc_arr_to_string(arr2.as_ptr(), 4i32); - if 0 != !(strcmp( - str_0, - b"0,12,133,1999999\x00" as *const u8 as *const libc::c_char, - ) == 0i32) as usize - { - __assert_rtn( - (*::std::mem::transmute::<&[u8; 17], &[libc::c_char; 17]>(b"stress_functions\x00")) - .as_ptr(), - b"../cmdline/stress.c\x00" as *const u8 as *const libc::c_char, - 665i32, - b"strcmp(str, \"0,12,133,1999999\")==0\x00" as *const u8 as *const libc::c_char, - ); - } else { - }; - free(str_0 as *mut libc::c_void); dc_array_empty(arr); dc_array_add_ptr( arr, @@ -2549,3 +2526,17 @@ fn test_stress_tests() { stress_functions(&context.ctx); } } + +#[test] +fn test_arr_to_string() { + let arr2: [uint32_t; 4] = [ + 0i32 as uint32_t, + 12i32 as uint32_t, + 133i32 as uint32_t, + 1999999i32 as uint32_t, + ]; + + let str_0 = unsafe { dc_arr_to_string(arr2.as_ptr(), 4i32) }; + assert_eq!(to_string(str_0), "0,12,133,1999999"); + unsafe { free(str_0 as *mut _) }; +}