refactor: remove libc usage of snprintf and strndup

This commit is contained in:
dignifiedquire
2019-05-29 22:04:30 +02:00
parent de0503bbab
commit cd45a1f37c
3 changed files with 77 additions and 48 deletions

View File

@@ -245,23 +245,18 @@ unsafe fn quote_word(
// col = (*mmapstr).len as libc::c_int;
cur = word;
while i < size {
let mut do_quote_char: libc::c_int = 0;
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,
let mut do_quote_char = false;
match *cur as u8 as char {
',' | ':' | '!' | '"' | '#' | '$' | '@' | '[' | '\\' | ']' | '^' | '`' | '{' | '|'
| '}' | '~' | '=' | '?' | '_' => do_quote_char = true,
_ => {
if *cur as libc::c_uchar as libc::c_int >= 128i32 {
do_quote_char = 1i32
if *cur as u8 >= 128 {
do_quote_char = true;
}
}
}
if 0 != do_quote_char {
snprintf(
hex.as_mut_ptr(),
4,
b"=%2.2X\x00" as *const u8 as *const libc::c_char,
*cur as libc::c_uchar as libc::c_int,
);
if do_quote_char {
print_hex(hex.as_mut_ptr(), cur);
if mmap_string_append(mmapstr, hex.as_mut_ptr()).is_null() {
return false;
}
@@ -716,6 +711,15 @@ pub unsafe fn dc_decode_ext_header(to_decode: *const libc::c_char) -> *mut libc:
};
}
unsafe fn print_hex(target: *mut libc::c_char, cur: *const libc::c_char) {
assert!(!target.is_null());
assert!(!cur.is_null());
let bytes = std::slice::from_raw_parts(cur as *const _, strlen(cur));
let raw = to_cstring(format!("={}", &hex::encode_upper(bytes)[..2]));
libc::memcpy(target as *mut _, raw.as_ptr() as *const _, 4);
}
#[cfg(test)]
mod tests {
use super::*;
@@ -882,4 +886,16 @@ mod tests {
);
}
}
#[test]
fn test_print_hex() {
let mut hex: [libc::c_char; 4] = [0; 4];
let cur = b"helloworld" as *const u8 as *const libc::c_char;
unsafe { print_hex(hex.as_mut_ptr(), cur) };
assert_eq!(to_string(hex.as_ptr() as *const _), "=68");
let cur = b":" as *const u8 as *const libc::c_char;
unsafe { print_hex(hex.as_mut_ptr(), cur) };
assert_eq!(to_string(hex.as_ptr() as *const _), "=3A");
}
}

View File

@@ -243,28 +243,13 @@ pub unsafe fn dc_null_terminate(
}
pub unsafe fn dc_binary_to_uc_hex(buf: *const uint8_t, bytes: size_t) -> *mut libc::c_char {
let mut hex: *mut libc::c_char = 0 as *mut libc::c_char;
let mut i;
if !(buf.is_null() || bytes <= 0) {
hex = calloc(
::std::mem::size_of::<libc::c_char>(),
bytes.wrapping_mul(2).wrapping_add(1),
) as *mut libc::c_char;
if !hex.is_null() {
i = 0;
while i < bytes {
snprintf(
&mut *hex.offset((i * 2) as isize) as *mut libc::c_char,
3,
b"%02X\x00" as *const u8 as *const libc::c_char,
*buf.offset(i as isize) as libc::c_int,
);
i += 1
}
}
if buf.is_null() || bytes == 0 {
return std::ptr::null_mut();
}
hex
let buf = std::slice::from_raw_parts(buf, bytes);
let raw = hex::encode_upper(buf);
strdup(to_cstring(raw).as_ptr())
}
/* remove all \r characters from string */
@@ -1820,4 +1805,15 @@ mod tests {
free(str as *mut libc::c_void);
}
}
#[test]
fn test_dc_binary_to_uc_hex() {
let buf = vec![0, 1, 2, 3, 255];
let raw = unsafe { dc_binary_to_uc_hex(buf.as_ptr(), buf.len()) };
let res = to_string(raw);
assert_eq!(res, "00010203FF");
unsafe { free(raw as *mut _) };
}
}

View File

@@ -1,4 +1,5 @@
use crate::dc_strbuilder::dc_strbuilder_t;
use crate::dc_tools::*;
use crate::types::*;
pub use libc::{
@@ -8,16 +9,30 @@ pub use libc::{
};
pub unsafe fn strdup(s: *const libc::c_char) -> *mut libc::c_char {
let slen = libc::strlen(s);
let result = libc::malloc(slen + 1);
if s.is_null() {
return std::ptr::null_mut();
}
let slen = strlen(s);
let result = malloc(slen + 1);
if result.is_null() {
return std::ptr::null_mut();
}
libc::memcpy(result, s as *const _, slen + 1);
memcpy(result, s as *const _, slen + 1);
result as *mut _
}
pub fn strndup(s: *const libc::c_char, n: libc::c_ulong) -> *mut libc::c_char {
if s.is_null() {
return std::ptr::null_mut();
}
let s_r = to_str(s);
let end = std::cmp::min(n as usize, s_r.len());
unsafe { strdup(to_cstring(&s_r[..end]).as_ptr()) }
}
extern "C" {
pub fn clock() -> libc::clock_t;
pub fn qsort(
@@ -29,7 +44,6 @@ extern "C" {
>,
);
pub fn pow(_: libc::c_double, _: libc::c_double) -> libc::c_double;
pub fn strndup(_: *const libc::c_char, _: libc::c_ulong) -> *mut libc::c_char;
pub fn strftime(
_: *mut libc::c_char,
_: size_t,
@@ -59,23 +73,12 @@ extern "C" {
_: *const libc::c_char,
) -> !;
#[cfg(windows)]
pub(crate) fn snprintf(
s: *mut libc::c_char,
n: libc::size_t,
format: *const libc::c_char,
_: ...
) -> libc::c_int;
// -- DC Methods
pub fn dc_strbuilder_catf(_: *mut dc_strbuilder_t, format: *const libc::c_char, _: ...);
pub fn dc_mprintf(format: *const libc::c_char, _: ...) -> *mut libc::c_char;
}
#[cfg(not(windows))]
pub(crate) use libc::snprintf;
#[cfg(not(target_os = "macos"))]
pub unsafe extern "C" fn __assert_rtn(
a: *const libc::c_char,
@@ -132,6 +135,7 @@ pub(crate) unsafe fn strncasecmp(
#[cfg(test)]
mod tests {
use super::*;
use crate::dc_tools::to_string;
#[test]
fn test_atox() {
@@ -140,4 +144,17 @@ mod tests {
assert_eq!(atoi(b"\x00" as *const u8 as *const libc::c_char), 0);
}
}
#[test]
fn test_strndup() {
unsafe {
let res = strndup(b"helloworld\x00" as *const u8 as *const libc::c_char, 4);
assert_eq!(
to_string(res),
to_string(b"hell\x00" as *const u8 as *const libc::c_char)
);
assert_eq!(strlen(res), 4);
free(res as *mut _);
}
}
}