fix some string issues, introduce to_string_lossy such that to_string() continues to panic on non-utf8

This commit is contained in:
holger krekel
2019-07-20 12:30:48 +02:00
parent 38eb708db8
commit d6de420b9a
4 changed files with 22 additions and 6 deletions

View File

@@ -843,7 +843,8 @@ unsafe fn hash_header(
} }
if !key.is_null() { if !key.is_null() {
let key_len: libc::c_int = strlen(key) as libc::c_int; let key_len: libc::c_int = strlen(key) as libc::c_int;
if out.contains_key(as_str(key)) { // XXX the optional field above may contain invalid UTF8
if out.contains_key(&to_string_lossy(key)) {
if (*field).fld_type != MAILIMF_FIELD_OPTIONAL_FIELD as libc::c_int if (*field).fld_type != MAILIMF_FIELD_OPTIONAL_FIELD as libc::c_int
|| key_len > 5i32 || key_len > 5i32
&& strncasecmp(key, b"Chat-\x00" as *const u8 as *const libc::c_char, 5) && strncasecmp(key, b"Chat-\x00" as *const u8 as *const libc::c_char, 5)

View File

@@ -503,10 +503,11 @@ pub unsafe fn dc_receive_imf(
} else { } else {
"" ""
}, },
// txt_raw might contain invalid utf8
if !txt_raw.is_null() { if !txt_raw.is_null() {
as_str(txt_raw) to_string_lossy(txt_raw)
} else { } else {
"" String::new()
}, },
as_str((*(*part).param).packed), as_str((*(*part).param).packed),
(*part).bytes, (*part).bytes,

View File

@@ -1561,9 +1561,20 @@ pub fn to_string(s: *const libc::c_char) -> String {
let cstr = unsafe { CStr::from_ptr(s) }; let cstr = unsafe { CStr::from_ptr(s) };
cstr.to_str().map(|s| s.to_string()).unwrap_or_else(|err| { cstr.to_str().map(|s| s.to_string()).unwrap_or_else(|err| {
let lossy = cstr.to_string_lossy(); panic!("Non utf8 string: '{:?}' ({:?})", cstr.to_string_lossy(), err);
eprintln!("Non utf8 string: '{:?}' ({:?})", lossy, err); })
lossy.to_string() }
pub fn to_string_lossy(s: *const libc::c_char) -> String {
if s.is_null() {
return "".into();
}
let cstr = unsafe { CStr::from_ptr(s) };
cstr.to_str().map(|s| s.to_string()).unwrap_or_else(|_| {
cstr.to_string_lossy().to_string()
}) })
} }

View File

@@ -89,6 +89,9 @@ impl Key {
} }
pub fn from_slice(bytes: &[u8], key_type: KeyType) -> Option<Self> { pub fn from_slice(bytes: &[u8], key_type: KeyType) -> Option<Self> {
if 0 == bytes.len() {
return None;
}
let res: Result<Key, _> = match key_type { let res: Result<Key, _> = match key_type {
KeyType::Public => SignedPublicKey::from_bytes(Cursor::new(bytes)).map(Into::into), KeyType::Public => SignedPublicKey::from_bytes(Cursor::new(bytes)).map(Into::into),
KeyType::Private => SignedSecretKey::from_bytes(Cursor::new(bytes)).map(Into::into), KeyType::Private => SignedSecretKey::from_bytes(Cursor::new(bytes)).map(Into::into),