diff --git a/CHANGELOG-Japanese.md b/CHANGELOG-Japanese.md index fddd88ded..868c5e4a9 100644 --- a/CHANGELOG-Japanese.md +++ b/CHANGELOG-Japanese.md @@ -7,6 +7,7 @@ - 指定した`status`のルールのみを利用する`--include-status`オプションを追加した。 (#1193) (@hitenkoku) - 未使用のクレートを削除した。(@YamatoSecurity) - SplunkからエクスポートしたJSONファイルの入力に対応した。 (#1083) (@hitenkoku) +- パフォーマンスの改善 (#1277, #1278) (@fukusuket) **バグ修正:** diff --git a/CHANGELOG.md b/CHANGELOG.md index c97ab8553..68a9cec89 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,8 @@ - Added `--include-status` option: You can specify rules based on their `status`. (#1193) (@hitenkoku) - Removed unused crates. (@YamatoSecurity) -- Adjusted JSON input file exported from Splunk. (#1083) (@hitenkoku) +- JSON input now supports the format exported from Splunk. (#1083) (@hitenkoku) +- Performance enchancements. (#1277, #1278) (@fukusuket) **Bug Fixes:** diff --git a/src/detections/rule/aggregation_parser.rs b/src/detections/rule/aggregation_parser.rs index bfe985d18..2b6d52fdc 100644 --- a/src/detections/rule/aggregation_parser.rs +++ b/src/detections/rule/aggregation_parser.rs @@ -88,29 +88,29 @@ impl AggegationConditionCompiler { &self, condition_str: String, ) -> Result, String> { - let mut cur_condition_str = condition_str; + let mut cur_condition_str = condition_str.as_str(); let mut tokens = Vec::new(); while !cur_condition_str.is_empty() { let captured = self::AGGREGATION_REGEXMAP.iter().find_map(|regex| { - return regex.captures(cur_condition_str.as_str()); + return regex.captures(cur_condition_str); }); if captured.is_none() { // トークンにマッチしないのはありえないという方針でパースしています。 return Result::Err("An unusable character was found.".to_string()); } - let mached_str = captured.unwrap().get(0).unwrap().as_str(); - let token = self.to_enum(mached_str.to_string()); + let matched_str = captured.unwrap().get(0).unwrap().as_str(); + let token = self.to_enum(matched_str); if let AggregationConditionToken::Space = token { // 空白は特に意味ないので、読み飛ばす。 - cur_condition_str = cur_condition_str.replacen(mached_str, "", 1); + cur_condition_str = &cur_condition_str[matched_str.len()..]; continue; } tokens.push(token); - cur_condition_str = cur_condition_str.replacen(mached_str, "", 1); + cur_condition_str = &cur_condition_str[matched_str.len()..]; } Result::Ok(tokens) @@ -226,7 +226,7 @@ impl AggegationConditionCompiler { } /// 文字列をConditionTokenに変換する。 - fn to_enum(&self, token: String) -> AggregationConditionToken { + fn to_enum(&self, token: &str) -> AggregationConditionToken { if token.starts_with("count(") { let count_field = token .replacen("count(", "", 1) @@ -248,7 +248,7 @@ impl AggegationConditionCompiler { } else if token == ">" { AggregationConditionToken::GT } else { - AggregationConditionToken::Keyword(token) + AggregationConditionToken::Keyword(token.to_string()) } } } diff --git a/src/detections/rule/condition_parser.rs b/src/detections/rule/condition_parser.rs index 2ed2c9621..c0d8c4dde 100644 --- a/src/detections/rule/condition_parser.rs +++ b/src/detections/rule/condition_parser.rs @@ -91,7 +91,7 @@ impl ConditionToken { }; } - pub fn to_condition_token(token: String) -> ConditionToken { + pub fn to_condition_token(token: &str) -> ConditionToken { if token == "(" { ConditionToken::LeftParenthesis } else if token == ")" { @@ -105,7 +105,7 @@ impl ConditionToken { } else if token == "or" { ConditionToken::Or } else { - ConditionToken::SelectionReference(token) + ConditionToken::SelectionReference(token.to_string()) } } } @@ -130,7 +130,7 @@ impl ConditionCompiler { let captured = self::RE_PIPE.captures(condition_str.as_str()); let replaced_condition = if let Some(cap) = captured { let captured = cap.get(0).unwrap().as_str(); - condition_str.replacen(captured, "", 1) + condition_str.replace(captured, "") } else { condition_str.to_string() }; @@ -191,28 +191,28 @@ impl ConditionCompiler { /// 字句解析を行う fn tokenize(&self, condition_str: &str) -> Result, String> { - let mut cur_condition_str = condition_str.to_string(); + let mut cur_condition_str = condition_str; let mut tokens = Vec::new(); while !cur_condition_str.is_empty() { let captured = self::CONDITION_REGEXMAP.iter().find_map(|regex| { - return regex.captures(cur_condition_str.as_str()); + return regex.captures(cur_condition_str); }); if captured.is_none() { // トークンにマッチしないのはありえないという方針でパースしています。 return Result::Err("An unusable character was found.".to_string()); } - let mached_str = captured.unwrap().get(0).unwrap().as_str(); - let token = ConditionToken::to_condition_token(mached_str.to_string()); + let matched_str = captured.unwrap().get(0).unwrap().as_str(); + let token = ConditionToken::to_condition_token(matched_str); if let ConditionToken::Space = token { // 空白は特に意味ないので、読み飛ばす。 - cur_condition_str = cur_condition_str.replacen(mached_str, "", 1); + cur_condition_str = &cur_condition_str[matched_str.len()..]; continue; } tokens.push(token); - cur_condition_str = cur_condition_str.replacen(mached_str, "", 1); + cur_condition_str = &cur_condition_str[matched_str.len()..]; } Result::Ok(tokens)