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),