# HG changeset patch # User alfadur # Date 1559676328 -10800 # Node ID cce6e707172f216f704118982bdc056c186e59f6 # Parent a7841105493e9b613490ace4ff60e75efa19e1d0 fix lists parsing diff -r a7841105493e -r cce6e707172f rust/hedgewars-server/src/protocol/parser.rs --- a/rust/hedgewars-server/src/protocol/parser.rs Tue Jun 04 20:01:37 2019 +0300 +++ b/rust/hedgewars-server/src/protocol/parser.rs Tue Jun 04 22:25:28 2019 +0300 @@ -84,8 +84,12 @@ } fn str_line(input: &[u8]) -> HwResult<&str> { - let (i, text) = not_line_ending(input)?; - Ok((i, convert_utf8(text)?.1)) + let (i, text) = not_line_ending(input.clone())?; + if i != input { + Ok((i, convert_utf8(text)?.1)) + } else { + Err(Err::Error(HwProtocolError::new())) + } } fn a_line(input: &[u8]) -> HwResult { @@ -103,8 +107,12 @@ fn cmd_arg(input: &[u8]) -> HwResult { let delimiters = b" \n"; - let (i, str) = take_while(move |c| !delimiters.contains(&c))(input)?; - Ok((i, convert_utf8(str)?.1.to_string())) + let (i, str) = take_while(move |c| !delimiters.contains(&c))(input.clone())?; + if i != input { + Ok((i, convert_utf8(str)?.1.to_string())) + } else { + Err(Err::Error(HwProtocolError::new())) + } } fn u8_line(input: &[u8]) -> HwResult { @@ -316,9 +324,15 @@ }, |i| { let (i, _) = tag_no_case("RND")(i)?; - let (i, _) = alt((spaces, peek(end_of_message)))(i)?; - let (i, v) = str_line(i)?; - Ok((i, Rnd(v.split_whitespace().map(String::from).collect()))) + let (i, v) = alt(( + |i| peek(end_of_message)(i).map(|(i, _)| (i, vec![])), + |i| { + let (i, _) = spaces(i)?; + let (i, v) = separated_list(spaces, cmd_arg)(i)?; + Ok((i, v)) + }, + ))(i)?; + Ok((i, Rnd(v))) }, )), ) @@ -574,8 +588,9 @@ #[cfg(test)] mod test { use super::message; - use crate::protocol::{ - messages::HwProtocolMessage::*, parser::HwProtocolError, test::gen_proto_msg, + use crate::{ + core::types::GameCfg, + protocol::{messages::HwProtocolMessage::*, parser::HwProtocolError, test::gen_proto_msg}, }; use proptest::{proptest, proptest_helper}; @@ -624,6 +639,14 @@ ); assert_eq!( + message(b"CFG\nSCHEME\na\nA\n\n"), + Ok(( + &b""[..], + Cfg(GameCfg::Scheme("a".to_string(), vec!["A".to_string()])) + )) + ); + + assert_eq!( message(b"QUIT\n1\n2\n\n"), Err(nom::Err::Error(HwProtocolError::new())) );