diff --git a/examples/repl/cmdline.rs b/examples/repl/cmdline.rs index 0e72396d1..204c71de9 100644 --- a/examples/repl/cmdline.rs +++ b/examples/repl/cmdline.rs @@ -450,6 +450,7 @@ pub unsafe fn dc_cmdline(context: &Context, line: &str) -> Result<(), failure::E dellocations\n\ getlocations []\n\ send \n\ + send-garbage\n\ sendimage []\n\ sendfile \n\ draft []\n\ @@ -948,6 +949,15 @@ pub unsafe fn dc_cmdline(context: &Context, line: &str) -> Result<(), failure::E bail!("Sending failed."); } } + "send-garbage" => { + ensure!(!sel_chat.is_null(), "No chat selected."); + let msg = b"\xff\x00"; // NUL-terminated C-string, that is malformed utf-8 + if 0 != dc_send_text_msg(context, dc_chat_get_id(sel_chat), msg.as_ptr().cast()) { + println!("Malformed utf-8 succesfully send. Not nice."); + } else { + bail!("Garbage sending failed, as expected."); + } + } "sendempty" => { ensure!(!sel_chat.is_null(), "No chat selected."); if 0 != dc_send_text_msg( diff --git a/examples/repl/main.rs b/examples/repl/main.rs index 28f923c3f..7cc700af8 100644 --- a/examples/repl/main.rs +++ b/examples/repl/main.rs @@ -3,6 +3,7 @@ //! //! Usage: cargo run --example repl --release -- //! All further options can be set using the set-command (type ? for help). +#![feature(ptr_cast)] #[macro_use] extern crate deltachat; @@ -290,7 +291,7 @@ const DB_COMMANDS: [&'static str; 11] = [ "housekeeping", ]; -const CHAT_COMMANDS: [&'static str; 24] = [ +const CHAT_COMMANDS: [&'static str; 25] = [ "listchats", "listarchived", "chat", @@ -308,6 +309,7 @@ const CHAT_COMMANDS: [&'static str; 24] = [ "dellocations", "getlocations", "send", + "send-garbage", "sendimage", "sendfile", "draft", diff --git a/src/dc_chat.rs b/src/dc_chat.rs index 6a819e8a5..0b4307484 100644 --- a/src/dc_chat.rs +++ b/src/dc_chat.rs @@ -976,6 +976,11 @@ pub unsafe fn dc_send_text_msg( return 0; } + if let Err(err) = as_str_safe(text_to_send) { + warn!(context, 0, "{}", err); + return 0; + } + let mut msg = dc_msg_new(context, 10); (*msg).text = dc_strdup(text_to_send); let ret = dc_send_msg(context, chat_id, msg); diff --git a/src/dc_tools.rs b/src/dc_tools.rs index d39317c7b..11fc46717 100644 --- a/src/dc_tools.rs +++ b/src/dc_tools.rs @@ -4,6 +4,7 @@ use std::fs; use std::time::SystemTime; use chrono::{Local, TimeZone}; +use failure::format_err; use mmime::mailimf_types::*; use rand::{thread_rng, Rng}; @@ -1563,13 +1564,16 @@ pub fn to_string_lossy(s: *const libc::c_char) -> String { } pub fn as_str<'a>(s: *const libc::c_char) -> &'a str { + as_str_safe(s).unwrap_or_else(|err| panic!("{}", err)) +} + +pub fn as_str_safe<'a>(s: *const libc::c_char) -> Result<&'a str, failure::Error> { assert!(!s.is_null(), "cannot be used on null pointers"); let cstr = unsafe { CStr::from_ptr(s) }; - cstr.to_str().unwrap_or_else(|err| { - panic!("Non utf8 string: '{:?}' ({:?})", cstr.to_bytes(), err); - }) + cstr.to_str() + .map_err(|err| format_err!("Non utf8 string: '{:?}' ({:?})", cstr.to_bytes(), err)) } /// Convert a C `*char` pointer to a [std::path::Path] slice.