From 929130564b9cbdb092f15b68377e61b13f0d94ef Mon Sep 17 00:00:00 2001 From: ko1N Date: Wed, 22 Feb 2023 01:06:49 +0100 Subject: [PATCH] Added more real-world argument parsing tests --- memflow/src/plugins/args.rs | 30 +++++++++++++++++++++++++++--- memflow/src/plugins/connector.rs | 14 +++++++++++++- memflow/src/plugins/os.rs | 2 +- 3 files changed, 41 insertions(+), 5 deletions(-) diff --git a/memflow/src/plugins/args.rs b/memflow/src/plugins/args.rs index 4c952576..fce5c361 100644 --- a/memflow/src/plugins/args.rs +++ b/memflow/src/plugins/args.rs @@ -125,6 +125,9 @@ impl std::str::FromStr for Args { } } + //let split: Vec<_> = split_str_args(s, ',').collect(); + + let mut map = HashMap::new(); for (i, kv) in split.iter().enumerate() { let kvsplit = kv.split('=').collect::>(); if kvsplit.len() == 2 { @@ -429,21 +432,22 @@ impl fmt::Debug for ArgDescriptor { /// let v: Vec<_> = split_str_args("a:\"hel:lo:c").collect(); /// assert_eq!(v, ["a", "\"hel:lo:c"]); /// ``` -pub fn split_str_args(inp: &str) -> impl Iterator { +pub fn split_str_args(inp: &str, split_char: char) -> impl Iterator { let mut prev_char = '\0'; let mut quotation_char = None; const VALID_QUOTES: &str = "\"'`"; + assert!(!VALID_QUOTES.contains(split_char)); inp.split(move |c| { - let ret = if c == ':' { + let ret = if c == split_char { let ret = quotation_char.is_none() || Some(prev_char) == quotation_char; if ret { quotation_char = None; } ret } else { - if prev_char == ':' && quotation_char.is_none() && VALID_QUOTES.contains(c) { + if prev_char == split_char && quotation_char.is_none() && VALID_QUOTES.contains(c) { quotation_char = Some(c); } false @@ -582,6 +586,26 @@ mod tests { assert_eq!(args2.get("opt2").unwrap(), "test2,test3=test4"); } + #[test] + pub fn slashes() { + let argstr = "device=vmware://,remote=rpc://insecure:computername.local"; + let args: Args = argstr.parse().unwrap(); + let args2: Args = args.to_string().parse().unwrap(); + assert_eq!(args2.get("device").unwrap(), "vmware://"); + assert_eq!( + args2.get("remote").unwrap(), + "rpc://insecure:computername.local" + ); + } + + #[test] + pub fn slashes_quotes() { + let argstr = "device=\"RAWUDP://ip=127.0.0.1\""; + let args: Args = argstr.parse().unwrap(); + let args2: Args = args.to_string().parse().unwrap(); + assert_eq!(args2.get("device").unwrap(), "RAWUDP://ip=127.0.0.1"); + } + #[test] pub fn validator_success() { let validator = ArgsValidator::new() diff --git a/memflow/src/plugins/connector.rs b/memflow/src/plugins/connector.rs index 278ff81d..48ac3c52 100644 --- a/memflow/src/plugins/connector.rs +++ b/memflow/src/plugins/connector.rs @@ -239,7 +239,7 @@ impl std::str::FromStr for ConnectorArgs { type Err = crate::error::Error; fn from_str(s: &str) -> Result { - let mut iter = split_str_args(s); + let mut iter = split_str_args(s, ':'); let target = iter .next() @@ -391,4 +391,16 @@ mod tests { assert_eq!(args.middleware_args.cache_validity_time, 10); assert_eq!(args.middleware_args.cache_page_size, 0x1000); } + + #[test] + pub fn connector_args_url() { + let args: ConnectorArgs = ":device=\"RAWUDP://ip=127.0.0.1:8080\":" + .parse() + .expect("unable to parse args"); + assert_eq!(args.target, None); + assert_eq!( + args.extra_args.get("device").unwrap(), + "RAWUDP://ip=127.0.0.1:8080" + ); + } } diff --git a/memflow/src/plugins/os.rs b/memflow/src/plugins/os.rs index ceb76c71..d694362e 100644 --- a/memflow/src/plugins/os.rs +++ b/memflow/src/plugins/os.rs @@ -48,7 +48,7 @@ impl std::str::FromStr for OsArgs { type Err = crate::error::Error; fn from_str(s: &str) -> Result { - let mut iter = split_str_args(s); + let mut iter = split_str_args(s, ':'); let target = iter .next()