From d6de420b9a7ae2af9dc233baa2ef301d9539eb94 Mon Sep 17 00:00:00 2001 From: holger krekel Date: Sat, 20 Jul 2019 12:30:48 +0200 Subject: [PATCH] fix some string issues, introduce to_string_lossy such that to_string() continues to panic on non-utf8 --- src/dc_mimeparser.rs | 3 ++- src/dc_receive_imf.rs | 5 +++-- src/dc_tools.rs | 17 ++++++++++++++--- src/key.rs | 3 +++ 4 files changed, 22 insertions(+), 6 deletions(-) diff --git a/src/dc_mimeparser.rs b/src/dc_mimeparser.rs index 6890510fd..8706c684e 100644 --- a/src/dc_mimeparser.rs +++ b/src/dc_mimeparser.rs @@ -843,7 +843,8 @@ unsafe fn hash_header( } if !key.is_null() { 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 || key_len > 5i32 && strncasecmp(key, b"Chat-\x00" as *const u8 as *const libc::c_char, 5) diff --git a/src/dc_receive_imf.rs b/src/dc_receive_imf.rs index 91e27ce63..d61d3384b 100644 --- a/src/dc_receive_imf.rs +++ b/src/dc_receive_imf.rs @@ -503,10 +503,11 @@ pub unsafe fn dc_receive_imf( } else { "" }, + // txt_raw might contain invalid utf8 if !txt_raw.is_null() { - as_str(txt_raw) + to_string_lossy(txt_raw) } else { - "" + String::new() }, as_str((*(*part).param).packed), (*part).bytes, diff --git a/src/dc_tools.rs b/src/dc_tools.rs index 33393b7f9..4e319d09e 100644 --- a/src/dc_tools.rs +++ b/src/dc_tools.rs @@ -1561,9 +1561,20 @@ pub fn to_string(s: *const libc::c_char) -> String { let cstr = unsafe { CStr::from_ptr(s) }; cstr.to_str().map(|s| s.to_string()).unwrap_or_else(|err| { - let lossy = cstr.to_string_lossy(); - eprintln!("Non utf8 string: '{:?}' ({:?})", lossy, err); - lossy.to_string() + panic!("Non utf8 string: '{:?}' ({:?})", cstr.to_string_lossy(), err); + }) +} + + +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() }) } diff --git a/src/key.rs b/src/key.rs index 4df2823db..5d4dd2b12 100644 --- a/src/key.rs +++ b/src/key.rs @@ -89,6 +89,9 @@ impl Key { } pub fn from_slice(bytes: &[u8], key_type: KeyType) -> Option { + if 0 == bytes.len() { + return None; + } let res: Result = match key_type { KeyType::Public => SignedPublicKey::from_bytes(Cursor::new(bytes)).map(Into::into), KeyType::Private => SignedSecretKey::from_bytes(Cursor::new(bytes)).map(Into::into),