using System; using System.Collections.Generic; using System.Linq; namespace BinaryObjectScanner.Matching { /// /// A set of path matches that work together /// public class PathMatchSet : MatchSet { /// /// Function to get a path version for this Matcher /// /// /// A path version method takes the matched path and an enumerable of files /// and returns a single string. That string is either a version string, /// in which case it will be appended to the protection name, or `null`, /// in which case it will cause the protection to be omitted. /// public Func, string> GetVersion { get; set; } #region Constructors public PathMatchSet(string needle, string protectionName) : this(new List { needle }, null, protectionName) { } public PathMatchSet(List needles, string protectionName) : this(needles, null, protectionName) { } public PathMatchSet(string needle, Func, string> getVersion, string protectionName) : this(new List { needle }, getVersion, protectionName) { } public PathMatchSet(List needles, Func, string> getVersion, string protectionName) : this(needles.Select(n => new PathMatch(n)).ToList(), getVersion, protectionName) { } public PathMatchSet(PathMatch needle, string protectionName) : this(new List() { needle }, null, protectionName) { } public PathMatchSet(List needles, string protectionName) : this(needles, null, protectionName) { } public PathMatchSet(PathMatch needle, Func, string> getVersion, string protectionName) : this(new List() { needle }, getVersion, protectionName) { } public PathMatchSet(List needles, Func, string> getVersion, string protectionName) { Matchers = needles; GetVersion = getVersion; ProtectionName = protectionName; } #endregion #region Matching /// /// Determine whether all path matches pass /// /// List of strings to try to match /// Tuple of passing status and matching values public (bool, List) MatchesAll(IEnumerable stack) { // If no path matches are defined, we fail out if (Matchers == null || !Matchers.Any()) return (false, new List()); // Initialize the value list List values = new List(); // Loop through all path matches and make sure all pass foreach (var pathMatch in Matchers) { (bool match, string value) = pathMatch.Match(stack); if (!match) return (false, new List()); else values.Add(value); } return (true, values); } /// /// Determine whether any path matches pass /// /// List of strings to try to match /// Tuple of passing status and first matching value public (bool, string) MatchesAny(IEnumerable stack) { // If no path matches are defined, we fail out if (Matchers == null || !Matchers.Any()) return (false, null); // Loop through all path matches and make sure all pass foreach (var pathMatch in Matchers) { (bool match, string value) = pathMatch.Match(stack); if (match) return (true, value); } return (false, null); } #endregion } }