From e0138ad7591ec2bc7c8d29632184f04117e819ed Mon Sep 17 00:00:00 2001 From: Till Wegmueller Date: Thu, 21 May 2020 12:04:47 +0200 Subject: [PATCH] Fixup Dir regex --- Cargo.toml | 2 +- src/actions/mod.rs | 67 +++++++++++++++++++++++++++------------------- src/lib.rs | 10 +++---- 3 files changed, 46 insertions(+), 33 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 32c6e61..1a6d293 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,7 +6,7 @@ [package] name = "libips" version = "0.1.0" -authors = ["Till Wegmueller "] +authors = ["Till Wegmueller "] edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/src/actions/mod.rs b/src/actions/mod.rs index dd8221f..1625c26 100644 --- a/src/actions/mod.rs +++ b/src/actions/mod.rs @@ -174,41 +174,54 @@ fn determine_action_kind(line: &str) -> ActionKind { fn parse_dir_action(line: String, line_nr: usize) -> Result { let mut act = Dir::default(); - let regex = Regex::new(r#"(([^ ]+)=([^"][^ ]+[^"])|([^ ]+)=([^"][^ ]+[^"]))"#)?; + let regex_set = RegexSet::new(&[ + r#"([^ ]+)=([^"][^ ]+[^"])"#, + r#"([^ ]+)="(.+)"# + ])?; - for cap in regex.captures_iter(line.trim_start()) { - match &cap[1] { - "path" => act.path = String::from(&cap[2]).replace(&['"', '\\'][..], ""), - "owner" => act.owner = String::from(&cap[2]).replace(&['"', '\\'][..], ""), - "group" => act.group = String::from(&cap[2]).replace(&['"', '\\'][..], ""), - "mode" => act.mode = String::from(&cap[2]).replace(&['"', '\\'][..], ""), - "revert-tag" => act.revert_tag = String::from(&cap[2]).replace(&['"', '\\'][..], ""), - "salvage-from" => act.salvage_from = String::from(&cap[2]).replace(&['"', '\\'][..], ""), - _ => { - let key_val_string = String::from(&cap[1]).replace(&['"', '\\'][..], ""); - if key_val_string.contains("facet.") { - let key = match key_val_string.find(".") { - Some(idx) => { - key_val_string.clone().split_off(idx+1) - }, - None => return Err(ManifestError::InvalidAction{action: line, line: line_nr, message: String::from("separation dot not found but string contains facet.")})? - }; + for pat in regex_set.matches(line.trim_start()).into_iter().map(|match_idx| ®ex_set.patterns()[match_idx]) { + let regex = Regex::new(&pat)?; - let value = match key_val_string.find("=") { - Some(idx) => { - key_val_string.clone().split_off(idx+1) - }, - None => return Err(ManifestError::InvalidAction{action: line, line: line_nr, message: String::from("no value present for facet")})? - }; + for cap in regex.captures_iter(line.trim_start()) { + let full_cap_idx = 0; + let key_cap_idx = 1; + let val_cap_idx = 2; - if !act.facets.insert(Facet{name: key, value: value}) { - return Err(ManifestError::InvalidAction{action: line, line: line_nr, message: String::from("double declaration of facet")})? + + match &cap[key_cap_idx] { + "path" => act.path = String::from(&cap[val_cap_idx]).trim_end().replace(&['"', '\\'][..], ""), + "owner" => act.owner = String::from(&cap[val_cap_idx]).trim_end().replace(&['"', '\\'][..], ""), + "group" => act.group = String::from(&cap[val_cap_idx]).trim_end().replace(&['"', '\\'][..], ""), + "mode" => act.mode = String::from(&cap[val_cap_idx]).trim_end().replace(&['"', '\\'][..], ""), + "revert-tag" => act.revert_tag = String::from(&cap[val_cap_idx]).trim_end().replace(&['"', '\\'][..], ""), + "salvage-from" => act.salvage_from = String::from(&cap[val_cap_idx]).trim_end().replace(&['"', '\\'][..], ""), + _ => { + let key_val_string = String::from(&cap[full_cap_idx]).trim_end().replace(&['"', '\\'][..], ""); + if key_val_string.contains("facet.") { + let key = match key_val_string.find(".") { + Some(idx) => { + key_val_string.clone().split_off(idx+1) + }, + None => return Err(ManifestError::InvalidAction{action: line, line: line_nr, message: String::from("separation dot not found but string contains facet.")})? + }; + + let value = match key_val_string.find("=") { + Some(idx) => { + key_val_string.clone().split_off(idx+1) + }, + None => return Err(ManifestError::InvalidAction{action: line, line: line_nr, message: String::from("no value present for facet")})? + }; + + if !act.facets.insert(Facet{name: key, value }) { + return Err(ManifestError::InvalidAction{action: line, line: line_nr, message: String::from("double declaration of facet")})? + } } } } } } + Ok(act) } @@ -239,7 +252,7 @@ fn parse_attr_action(line: String) -> Result { } val = val.replace(&['"', '\\'][..], ""); - //TODO knock out single quotes somehow + //TODO knock out single quotes somehow without if !fast_path_fail{ return Ok(Attr{ diff --git a/src/lib.rs b/src/lib.rs index ea47f1f..b06cc52 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -151,8 +151,8 @@ mod tests { let manifest_string = String::from("dir group=bin mode=0755 owner=root path=etc/nginx dir group=bin mode=0755 owner=root path=usr/share/nginx dir group=bin mode=0755 owner=root path=usr/share/nginx/html - dir group=bin mode=0755 owner=root path=\"var/nginx\" - dir group=bin mode=0755 owner=webservd path=var/nginx/logs"); + dir group=bin mode=0755 owner=webservd path=var/nginx/logs + dir group=bin mode=0755 owner=root path=\"var/nginx\""); let test_results = vec![ Dir{ @@ -176,14 +176,14 @@ mod tests { },Dir{ group: String::from("bin"), mode: String::from("0755"), - owner: String::from("root"), - path: String::from("\"var/nginx\""), + owner: String::from("webservd"), + path: String::from("var/nginx/logs"), ..Dir::default() },Dir{ group: String::from("bin"), mode: String::from("0755"), owner: String::from("root"), - path: String::from("var/nginx/logs"), + path: String::from("var/nginx"), ..Dir::default() }, ];