rust/hedgewars-server/src/protocol/parser.rs
changeset 15121 cce6e707172f
parent 15119 a7841105493e
child 15123 0e59abde6766
--- 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<String> {
@@ -103,8 +107,12 @@
 
 fn cmd_arg(input: &[u8]) -> HwResult<String> {
     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<u8> {
@@ -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()))
         );