From a9c714748df266506a51fe30a07875fb086d5139 Mon Sep 17 00:00:00 2001 From: Dmitry Bogatov Date: Sat, 27 Jul 2019 00:02:28 +0000 Subject: [PATCH] Make repl program more robust This change replaces calls to unwrap() function with "?" operator, propagating error up the call stack. This way "chat foo" (for example) command results in Error: invalid digit found in string message instead of crashing whole repl. --- examples/repl/cmdline.rs | 45 ++++++++++++++++++++-------------------- 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/examples/repl/cmdline.rs b/examples/repl/cmdline.rs index 0e72396d1..749826367 100644 --- a/examples/repl/cmdline.rs +++ b/examples/repl/cmdline.rs @@ -523,7 +523,7 @@ pub unsafe fn dc_cmdline(context: &Context, line: &str) -> Result<(), failure::E } "get-setupcodebegin" => { ensure!(!arg1.is_empty(), "Argument missing."); - let msg_id: u32 = arg1.parse().unwrap(); + let msg_id: u32 = arg1.parse()?; let msg: *mut dc_msg_t = dc_get_msg(context, msg_id); if dc_msg_is_setupmessage(msg) { let setupcodebegin = dc_msg_get_setupcodebegin(msg); @@ -543,7 +543,7 @@ pub unsafe fn dc_cmdline(context: &Context, line: &str) -> Result<(), failure::E !arg1.is_empty() && !arg2.is_empty(), "Arguments expected" ); - if 0 == dc_continue_key_transfer(context, arg1.parse().unwrap(), arg2_c) { + if 0 == dc_continue_key_transfer(context, arg1.parse()?, arg2_c) { bail!("Continue key transfer failed"); } } @@ -599,7 +599,7 @@ pub unsafe fn dc_cmdline(context: &Context, line: &str) -> Result<(), failure::E } "reset" => { ensure!(!arg1.is_empty(), "Argument missing: 1=jobs, 2=peerstates, 4=private keys, 8=rest but server config"); - let bits: i32 = arg1.parse().unwrap(); + let bits: i32 = arg1.parse()?; ensure!(bits < 16, " must be lower than 16."); ensure!(0 != dc_reset_tables(context, bits), "Reset failed"); } @@ -715,7 +715,7 @@ pub unsafe fn dc_cmdline(context: &Context, line: &str) -> Result<(), failure::E dc_chat_unref(sel_chat); } if !arg1.is_empty() { - let chat_id = arg1.parse().unwrap(); + let chat_id = arg1.parse()?; println!("Selecting chat #{}", chat_id); sel_chat = dc_get_chat(context, chat_id); *context.cmdline_sel_chat_id.write().unwrap() = chat_id; @@ -759,7 +759,7 @@ pub unsafe fn dc_cmdline(context: &Context, line: &str) -> Result<(), failure::E } "createchat" => { ensure!(!arg1.is_empty(), "Argument missing."); - let contact_id: libc::c_int = arg1.parse().unwrap(); + let contact_id: libc::c_int = arg1.parse()?; let chat_id: libc::c_int = dc_create_chat_by_contact_id(context, contact_id as uint32_t) as libc::c_int; if chat_id != 0 { @@ -770,7 +770,7 @@ pub unsafe fn dc_cmdline(context: &Context, line: &str) -> Result<(), failure::E } "createchatbymsg" => { ensure!(!arg1.is_empty(), "Argument missing"); - let msg_id_0: libc::c_int = arg1.parse().unwrap(); + let msg_id_0: libc::c_int = arg1.parse()?; let chat_id_0: libc::c_int = dc_create_chat_by_msg_id(context, msg_id_0 as uint32_t) as libc::c_int; if chat_id_0 != 0 { @@ -807,7 +807,7 @@ pub unsafe fn dc_cmdline(context: &Context, line: &str) -> Result<(), failure::E ensure!(!sel_chat.is_null(), "No chat selected"); ensure!(!arg1.is_empty(), "Argument missing."); - let contact_id_0: libc::c_int = arg1.parse().unwrap(); + let contact_id_0: libc::c_int = arg1.parse()?; if 0 != dc_add_contact_to_chat( context, dc_chat_get_id(sel_chat), @@ -821,7 +821,7 @@ pub unsafe fn dc_cmdline(context: &Context, line: &str) -> Result<(), failure::E "removemember" => { ensure!(!sel_chat.is_null(), "No chat selected."); ensure!(!arg1.is_empty(), "Argument missing."); - let contact_id_1: libc::c_int = arg1.parse().unwrap(); + let contact_id_1: libc::c_int = arg1.parse()?; if 0 != dc_remove_contact_from_chat( context, dc_chat_get_id(sel_chat), @@ -912,7 +912,7 @@ pub unsafe fn dc_cmdline(context: &Context, line: &str) -> Result<(), failure::E ensure!(!sel_chat.is_null(), "No chat selected."); ensure!(!arg1.is_empty(), "No timeout given."); - let seconds = arg1.parse().unwrap(); + let seconds = arg1.parse()?; dc_send_locations_to_chat(context, dc_chat_get_id(sel_chat), seconds); println!("Locations will be sent to Chat#{} for {} seconds. Use 'setlocation ' to play around.", dc_chat_get_id(sel_chat), seconds); } @@ -921,8 +921,8 @@ pub unsafe fn dc_cmdline(context: &Context, line: &str) -> Result<(), failure::E !arg1.is_empty() && !arg2.is_empty(), "Latitude or longitude not given." ); - let latitude = arg1.parse().unwrap(); - let longitude = arg2.parse().unwrap(); + let latitude = arg1.parse()?; + let longitude = arg2.parse()?; let continue_streaming = dc_set_location(context, latitude, longitude, 0.); if 0 != continue_streaming { @@ -1020,17 +1020,17 @@ pub unsafe fn dc_cmdline(context: &Context, line: &str) -> Result<(), failure::E } "archive" | "unarchive" => { ensure!(!arg1.is_empty(), "Argument missing."); - let chat_id = arg1.parse().unwrap(); + let chat_id = arg1.parse()?; dc_archive_chat(context, chat_id, if arg0 == "archive" { 1 } else { 0 }); } "delchat" => { ensure!(!arg1.is_empty(), "Argument missing."); - let chat_id = arg1.parse().unwrap(); + let chat_id = arg1.parse()?; dc_delete_chat(context, chat_id); } "msginfo" => { ensure!(!arg1.is_empty(), "Argument missing."); - let id = arg1.parse().unwrap(); + let id = arg1.parse()?; let res = dc_get_msg_info(context, id); println!("{}", as_str(res)); } @@ -1049,20 +1049,20 @@ pub unsafe fn dc_cmdline(context: &Context, line: &str) -> Result<(), failure::E ); let mut msg_ids = [0; 1]; - let chat_id = arg2.parse().unwrap(); - msg_ids[0] = arg1.parse().unwrap(); + let chat_id = arg2.parse()?; + msg_ids[0] = arg1.parse()?; dc_forward_msgs(context, msg_ids.as_mut_ptr(), 1, chat_id); } "markseen" => { ensure!(!arg1.is_empty(), "Argument missing."); let mut msg_ids = [0; 1]; - msg_ids[0] = arg1.parse().unwrap(); + msg_ids[0] = arg1.parse()?; dc_markseen_msgs(context, msg_ids.as_mut_ptr(), 1); } "star" | "unstar" => { ensure!(!arg1.is_empty(), "Argument missing."); let mut msg_ids = [0; 1]; - msg_ids[0] = arg1.parse().unwrap(); + msg_ids[0] = arg1.parse()?; dc_star_msgs( context, msg_ids.as_mut_ptr(), @@ -1073,7 +1073,7 @@ pub unsafe fn dc_cmdline(context: &Context, line: &str) -> Result<(), failure::E "delmsg" => { ensure!(!arg1.is_empty(), "Argument missing."); let mut ids = [0; 1]; - ids[0] = arg1.parse().unwrap(); + ids[0] = arg1.parse()?; dc_delete_msgs(context, ids.as_mut_ptr(), 1); } "listcontacts" | "contacts" | "listverified" => { @@ -1114,7 +1114,7 @@ pub unsafe fn dc_cmdline(context: &Context, line: &str) -> Result<(), failure::E "contactinfo" => { ensure!(!arg1.is_empty(), "Argument missing."); - let contact_id = arg1.parse().unwrap(); + let contact_id = arg1.parse()?; let contact = dc_get_contact(context, contact_id); let name_n_addr = dc_contact_get_name_n_addr(contact); @@ -1147,7 +1147,7 @@ pub unsafe fn dc_cmdline(context: &Context, line: &str) -> Result<(), failure::E } "delcontact" => { ensure!(!arg1.is_empty(), "Argument missing."); - if !dc_delete_contact(context, arg1.parse().unwrap()) { + if !dc_delete_contact(context, arg1.parse()?) { bail!("Failed to delete contact"); } } @@ -1165,7 +1165,8 @@ pub unsafe fn dc_cmdline(context: &Context, line: &str) -> Result<(), failure::E } "event" => { ensure!(!arg1.is_empty(), "Argument missing."); - let event = Event::from_u32(arg1.parse().unwrap()).unwrap(); + let event = arg1.parse()?; + let event = Event::from_u32(event).ok_or(format_err!("Event::from_u32({})", event))?; let r = context.call_cb(event, 0 as uintptr_t, 0 as uintptr_t); println!( "Sending event {:?}({}), received value {}.",